Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/inc/nx_api.h
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/inc/nx_api.h	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/inc/nx_api.h	(revision 69)
@@ -0,0 +1,4074 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Application Interface (API)                                         */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  APPLICATION INTERFACE DEFINITION                       RELEASE        */
+/*                                                                        */
+/*    nx_api.h                                            PORTABLE C      */
+/*                                                           6.4.0        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This file defines the basic Application Interface (API) to the      */
+/*    high-performance NetX TCP/IP implementation for the ThreadX         */
+/*    real-time kernel.  All service prototypes and data structure        */
+/*    definitions are defined in this file. Please note that basic data   */
+/*    type definitions and other architecture-specific information is     */
+/*    contained in the file nx_port.h.                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s), fixed    */
+/*                                            ThreadX version check,      */
+/*                                            updated product constants,  */
+/*                                            resulting in version 6.1    */
+/*  11-09-2020     Yuxin Zhou               Modified comment(s), and      */
+/*                                            updated product constants,  */
+/*                                            resulting in version 6.1.2  */
+/*  12-31-2020     Yuxin Zhou               Modified comment(s), added    */
+/*                                            PTP timestamp capability,   */
+/*                                            added function to convert   */
+/*                                            string to unsigned integer, */
+/*                                            updated product constants,  */
+/*                                            resulting in version 6.1.3  */
+/*  02-02-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            updated product constants,  */
+/*                                            resulting in version 6.1.4  */
+/*  03-02-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            updated product constants,  */
+/*                                            resulting in version 6.1.5  */
+/*  04-02-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            added functions for base64, */
+/*                                            resulting in version 6.1.6  */
+/*  06-02-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            updated product constants,  */
+/*                                            resulting in version 6.1.7  */
+/*  08-02-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            supported TCP/IP offload,   */
+/*                                            added new ip filter,        */
+/*                                            added function to convert   */
+/*                                            unsigned integer to string, */
+/*                                            resulting in version 6.1.8  */
+/*  10-15-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            added support for getting   */
+/*                                            interface type,             */
+/*                                            resulting in version 6.1.9  */
+/*  01-31-2022     Yuxin Zhou               Modified comment(s), and      */
+/*                                            updated product constants,  */
+/*                                            resulting in version 6.1.10 */
+/*  04-25-2022     Yuxin Zhou               Modified comment(s), and      */
+/*                                            updated product constants,  */
+/*                                            added internal ip address   */
+/*                                            change notification,        */
+/*                                            resulting in version 6.1.11 */
+/*  07-29-2022     Yuxin Zhou               Modified comment(s), and      */
+/*                                            updated product constants,  */
+/*                                            fixed compiler errors when  */
+/*                                            TX_SAFETY_CRITICAL is       */
+/*                                            enabled,                    */
+/*                                            resulting in version 6.1.12 */
+/*  10-31-2022     Wenhui Xie               Modified comment(s), and      */
+/*                                            supported HTTP Proxy,       */
+/*                                            resulting in version 6.2.0  */
+/*  03-08-2023     Tiejun Zhou              Modified comment(s), and      */
+/*                                            updated product constants,  */
+/*                                            resulting in version 6.2.1  */
+/*  10-31-2023     Tiejun Zhou              Modified comment(s),          */
+/*                                            supported random IP id,     */
+/*                                            resulting in version 6.3.0  */
+/*  12-31-2023     Yajun Xia                Modified comment(s),          */
+/*                                            supported VLAN and generic  */
+/*                                            link layer,                 */
+/*                                            resulting in version 6.4.0  */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef NX_API_H
+#define NX_API_H
+
+/* Determine if a C++ compiler is being used.  If so, ensure that standard
+   C is used to process the API information.  */
+
+#ifdef __cplusplus
+
+/* Yes, C++ compiler is present.  Use standard C.  */
+extern   "C" {
+
+#endif
+
+
+/* Disable warning of parameter not used. */
+#ifndef NX_PARAMETER_NOT_USED
+#define NX_PARAMETER_NOT_USED(p) ((void)(p))
+#endif /* NX_PARAMETER_NOT_USED */
+
+
+/* Bypass ThreadX API error checking for internal NetX calls.  */
+#include "tx_port.h"
+
+#ifdef NX_SOURCE_CODE
+#ifndef TX_SAFETY_CRITICAL
+#ifndef TX_DISABLE_ERROR_CHECKING
+#define TX_DISABLE_ERROR_CHECKING
+#endif
+#endif
+#endif
+
+
+
+/* Include the ThreadX and port-specific data type file.  */
+
+#include "tx_api.h"
+#include "nx_port.h"
+
+#ifdef NX_IPSEC_ENABLE
+#include "nx_crypto_const.h"
+#endif /* NX_IPSEC_ENABLE */
+/* Include the ThreadX trace information.  */
+
+#include "tx_trace.h"
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+#ifndef NX_ENABLE_INTERFACE_CAPABILITY
+#error "NX_ENABLE_INTERFACE_CAPABILITY must be defined to enable TCP/IP offload"
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+/* Define symbols for compatibility before and after ThreadX 5.8. */
+#if (((THREADX_MAJOR_VERSION << 8) | THREADX_MINOR_VERSION) >= 0x0508)
+#define NX_CLEANUP_PARAMETER , ULONG suspension_sequence
+#define NX_CLEANUP_ARGUMENT  , 0
+#define NX_CLEANUP_EXTENSION NX_PARAMETER_NOT_USED(suspension_sequence);
+#else
+#define NX_CLEANUP_PARAMETER
+#define NX_CLEANUP_ARGUMENT
+#define NX_CLEANUP_EXTENSION
+#endif /* (((THREADX_MAJOR_VERSION << 8) | THREADX_MINOR_VERSION) >= 0x0508) */
+
+/* Define the get system state macro. By default, it simply maps to the variable _tx_thread_system_state.  */
+#ifndef TX_THREAD_GET_SYSTEM_STATE
+#define TX_THREAD_GET_SYSTEM_STATE()                        _tx_thread_system_state
+#endif
+
+/* Define basic alignment type used in block and byte pool operations. This data type must
+   be at least 32-bits in size and also be large enough to hold a pointer type.  */
+
+#ifndef ALIGN_TYPE_DEFINED
+#define ALIGN_TYPE      ULONG
+#endif
+
+
+/* Define the extension to hold the control block.  */
+#ifndef NX_THREAD_EXTENSION_PTR_SET
+#define NX_THREAD_EXTENSION_PTR_SET(a, b)
+#endif /* NX_THREAD_EXTENSION_PTR_SET  */
+
+#ifndef NX_THREAD_EXTENSION_PTR_GET
+#define NX_THREAD_EXTENSION_PTR_GET(a, b, c)                { \
+                                                                (a) = (b *)(c); \
+                                                            }
+#endif /* NX_THREAD_EXTENSION_PTR_GET  */
+
+#ifndef NX_TIMER_EXTENSION_PTR_SET
+#define NX_TIMER_EXTENSION_PTR_SET(a, b)
+#endif /* NX_TIMER_EXTENSION_PTR_SET  */
+
+#ifndef NX_TIMER_EXTENSION_PTR_GET
+#define NX_TIMER_EXTENSION_PTR_GET(a, b, c)                 { \
+                                                                (a) = (b *)(c); \
+                                                            }
+#endif /* NX_TIMER_EXTENSION_PTR_GET  */
+
+
+#ifdef TX_UCHAR_POINTER_ADD
+#define NX_UCHAR_POINTER_ADD(a,b)                           TX_UCHAR_POINTER_ADD(a,b)
+#else
+#define NX_UCHAR_POINTER_ADD(a,b)                           (((UCHAR *) (a)) + ((UINT) (b)))
+#endif
+
+
+/* The symbol "NX_IP_PERIODIC_RATE" specifies the number of ThreadX timer ticks in one second.
+   The value should be derived from TX_TIMER_TICKS_PER_SECOND, which is defined in ThreadX port.
+   If TX_TIMER_TICKS_PER_SECOND is not defined, NX_IP_PERIODIC_RATE defaults to 100 ticks per second. */
+
+#ifndef NX_IP_PERIODIC_RATE
+#ifdef TX_TIMER_TICKS_PER_SECOND
+#define NX_IP_PERIODIC_RATE                                 TX_TIMER_TICKS_PER_SECOND
+#else
+#define NX_IP_PERIODIC_RATE                                 100
+#endif
+#endif
+
+
+/* This defines the ASSET and process on ASSET fail. */
+#ifndef NX_DISABLE_ASSERT
+#ifndef NX_ASSERT_FAIL
+#define NX_ASSERT_FAIL                                      for (;;) {tx_thread_sleep(NX_WAIT_FOREVER); }
+#endif /* NX_ASSERT_FAIL */
+#define NX_ASSERT(s)                                        if (!(s)) {NX_ASSERT_FAIL}
+#else
+#define NX_ASSERT(s)
+#endif /* NX_DISABLE_ASSERT */
+
+
+#ifndef NX_RAND
+#ifdef NX_HIGH_SECURITY
+#error "The symbol NX_RAND must be defined to use a qualified random number generator."
+#else
+#define NX_RAND                                             rand
+#endif
+#endif
+
+#ifndef NX_SRAND
+#ifdef NX_HIGH_SECURITY
+#error "The symbol NX_SRAND must be defined to use a qualified random number seed."
+#else
+#define NX_SRAND                                            srand
+#endif
+#endif
+
+
+/* Define the max string length.  */
+#ifndef NX_MAX_STRING_LENGTH
+#define NX_MAX_STRING_LENGTH                                1024
+#endif  /* NX_MAX_STRING_LENGTH */
+
+
+/* Determine if tracing is enabled.  */
+
+#ifdef TX_ENABLE_EVENT_TRACE
+
+/* Define the object types in NetX, if not defined.  */
+
+#ifndef NX_TRACE_OBJECT_TYPE_IP
+#define NX_TRACE_OBJECT_TYPE_IP                             11          /* P1 = stack start address, P2 = stack size    */
+#define NX_TRACE_OBJECT_TYPE_PACKET_POOL                    12          /* P1 = packet size, P2 = number of packets     */
+#define NX_TRACE_OBJECT_TYPE_TCP_SOCKET                     13          /* P1 = IP address, P2 = window size            */
+#define NX_TRACE_OBJECT_TYPE_UDP_SOCKET                     14          /* P1 = IP address, P2 = receive queue maximum  */
+#endif
+
+
+/* Define event filters that can be used to selectively disable certain events or groups of events.  */
+
+#define NX_TRACE_ALL_EVENTS                                 0x00FF8000  /* All NetX events                           */
+#define NX_TRACE_INTERNAL_EVENTS                            0x00008000  /* NetX internal events                      */
+#define NX_TRACE_ARP_EVENTS                                 0x00010000  /* NetX ARP events                           */
+#define NX_TRACE_ICMP_EVENTS                                0x00020000  /* NetX ICMP events                          */
+#define NX_TRACE_IGMP_EVENTS                                0x00040000  /* NetX IGMP events                          */
+#define NX_TRACE_IP_EVENTS                                  0x00080000  /* NetX IP events                            */
+#define NX_TRACE_PACKET_EVENTS                              0x00100000  /* NetX Packet events                        */
+#define NX_TRACE_RARP_EVENTS                                0x00200000  /* NetX RARP events                          */
+#define NX_TRACE_TCP_EVENTS                                 0x00400000  /* NetX TCP events                           */
+#define NX_TRACE_UDP_EVENTS                                 0x00800000  /* NetX UDP events                           */
+
+
+/* Define the trace events in NetX, if not defined.  */
+
+/* Define NetX Trace Events, along with a brief description of the additional information fields,
+   where I1 -> Information Field 1, I2 -> Information Field 2, etc.  */
+
+/* Define the NetX internal events first.  */
+
+#ifndef NX_TRACE_INTERNAL_ARP_REQUEST_RECEIVE
+#define NX_TRACE_INTERNAL_ARP_REQUEST_RECEIVE               300         /* I1 = ip ptr, I2 = source IP address, I3 = packet ptr                     */
+#define NX_TRACE_INTERNAL_ARP_REQUEST_SEND                  301         /* I1 = ip ptr, I2 = destination IP address, I3 = packet ptr                */
+#define NX_TRACE_INTERNAL_ARP_RESPONSE_RECEIVE              302         /* I1 = ip ptr, I2 = source IP address, I3 = packet ptr                     */
+#define NX_TRACE_INTERNAL_ARP_RESPONSE_SEND                 303         /* I1 = ip ptr, I2 = destination IP address, I3 = packet ptr                */
+#define NX_TRACE_INTERNAL_ICMP_RECEIVE                      304         /* I1 = ip ptr, I2 = source IP address, I3 = packet ptr, I4 = header word 0 */
+#define NX_TRACE_INTERNAL_ICMP_SEND                         305         /* I1 = ip ptr, I2 = destination IP address, I3 = packet ptr, I4 = header 0 */
+#define NX_TRACE_INTERNAL_IGMP_RECEIVE                      306         /* I1 = ip ptr, I2 = source IP address, I3 = packet ptr, I4 = header word 0 */
+
+#define NX_TRACE_INTERNAL_IP_RECEIVE                        308         /* I1 = ip ptr, I2 = source IP address, I3 = packet ptr, I4 = packet length */
+#define NX_TRACE_INTERNAL_IP_SEND                           309         /* I1 = ip ptr, I2 = destination IP address, I3 = packet ptr, I4 = length   */
+#define NX_TRACE_INTERNAL_TCP_DATA_RECEIVE                  310         /* I1 = ip ptr, I2 = source IP address, I3 = packet ptr, I4 = sequence      */
+#define NX_TRACE_INTERNAL_TCP_DATA_SEND                     311         /* I1 = ip ptr, I2 = socket ptr, I3 = packet ptr, I4 = sequence             */
+#define NX_TRACE_INTERNAL_TCP_FIN_RECEIVE                   312         /* I1 = ip ptr, I2 = socket ptr, I3 = packet ptr, I4 = sequence             */
+#define NX_TRACE_INTERNAL_TCP_FIN_SEND                      313         /* I1 = ip ptr, I2 = socket ptr, I3 = packet ptr, I4 = sequence             */
+#define NX_TRACE_INTERNAL_TCP_RESET_RECEIVE                 314         /* I1 = ip ptr, I2 = socket ptr, I3 = packet ptr, I4 = sequence             */
+#define NX_TRACE_INTERNAL_TCP_RESET_SEND                    315         /* I1 = ip ptr, I2 = socket ptr, I3 = packet ptr, I4 = sequence             */
+#define NX_TRACE_INTERNAL_TCP_SYN_RECEIVE                   316         /* I1 = ip ptr, I2 = socket ptr, I3 = packet ptr, I4 = sequence             */
+#define NX_TRACE_INTERNAL_TCP_SYN_SEND                      317         /* I1 = ip ptr, I2 = socket ptr, I3 = packet ptr, I4 = sequence             */
+#define NX_TRACE_INTERNAL_UDP_RECEIVE                       318         /* I1 = ip ptr, I2 = socket ptr, I3 = packet ptr, I4 = header word 0        */
+#define NX_TRACE_INTERNAL_UDP_SEND                          319         /* I1 = ip ptr, I2 = socket_ptr, I3 = packet ptr, I4 = header 0             */
+#define NX_TRACE_INTERNAL_RARP_RECEIVE                      320         /* I1 = ip ptr, I2 = target IP address, I3 = packet ptr, I4 = header word 1 */
+#define NX_TRACE_INTERNAL_RARP_SEND                         321         /* I1 = ip ptr, I2 = target IP address, I3 = packet ptr, I4 = header word 1 */
+#define NX_TRACE_INTERNAL_TCP_RETRY                         322         /* I1 = ip ptr, I2 = socket ptr, I3 = packet ptr, I4 = number of retries    */
+#define NX_TRACE_INTERNAL_TCP_STATE_CHANGE                  323         /* I1 = ip ptr, I2 = socket ptr, I3 = previous state, I4 = new state        */
+#define NX_TRACE_INTERNAL_IO_DRIVER_PACKET_SEND             324         /* I1 = ip ptr, I2 = packet ptr, I3 = packet size                           */
+#define NX_TRACE_INTERNAL_IO_DRIVER_INITIALIZE              325         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_LINK_ENABLE             326         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_LINK_DISABLE            327         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_PACKET_BROADCAST        328         /* I1 = ip ptr, I2 = packet ptr, I3 = packet size                           */
+#define NX_TRACE_INTERNAL_IO_DRIVER_ARP_SEND                329         /* I1 = ip ptr, I2 = packet ptr, I3 = packet size                           */
+#define NX_TRACE_INTERNAL_IO_DRIVER_ARP_RESPONSE_SEND       330         /* I1 = ip ptr, I2 = packet ptr, I3 = packet size                           */
+#define NX_TRACE_INTERNAL_IO_DRIVER_RARP_SEND               331         /* I1 = ip ptr, I2 = packet ptr, I3 = packet size                           */
+#define NX_TRACE_INTERNAL_IO_DRIVER_MULTICAST_JOIN          332         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_MULTICAST_LEAVE         333         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_GET_STATUS              334         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_GET_SPEED               335         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_GET_DUPLEX_TYPE         336         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_GET_ERROR_COUNT         337         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_GET_RX_COUNT            338         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_GET_TX_COUNT            339         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_GET_ALLOC_ERRORS        340         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_UNINITIALIZE            341         /* I1 = ip ptr                                                              */
+#define NX_TRACE_INTERNAL_IO_DRIVER_DEFERRED_PROCESSING     342         /* I1 = ip ptr, I2 = packet ptr, I3 = packet size                           */
+
+#define NX_TRACE_ARP_DYNAMIC_ENTRIES_INVALIDATE             350         /* I1 = ip ptr, I2 = entries invalidated                                    */
+#define NX_TRACE_ARP_DYNAMIC_ENTRY_SET                      351         /* I1 = ip ptr, I2 = ip address, I3 = physical msw, I4 = physical lsw       */
+#define NX_TRACE_ARP_ENABLE                                 352         /* I1 = ip ptr, I2 = arp cache memory, I3 = arp cache size                  */
+#define NX_TRACE_ARP_GRATUITOUS_SEND                        353         /* I1 = ip ptr                                                              */
+#define NX_TRACE_ARP_HARDWARE_ADDRESS_FIND                  354         /* I1 = ip ptr, I2 = ip_address, I3 = physical msw, I4 = physical lsw       */
+#define NX_TRACE_ARP_INFO_GET                               355         /* I1 = ip ptr, I2 = arps sent, I3 = arp responses, I3 = arps received      */
+#define NX_TRACE_ARP_IP_ADDRESS_FIND                        356         /* I1 = ip ptr, I2 = ip address, I3 = physical msw, I4 = physical lsw       */
+#define NX_TRACE_ARP_STATIC_ENTRIES_DELETE                  357         /* I1 = ip ptr, I2 = entries deleted                                        */
+#define NX_TRACE_ARP_STATIC_ENTRY_CREATE                    358         /* I1 = ip ptr, I2 = ip address, I3 = physical msw, I4 = physical_lsw       */
+#define NX_TRACE_ARP_STATIC_ENTRY_DELETE                    359         /* I1 = ip ptr, I2 = ip address, I3 = physical_msw, I4 = physical_lsw       */
+#define NX_TRACE_ICMP_ENABLE                                360         /* I1 = ip ptr                                                              */
+#define NX_TRACE_ICMP_INFO_GET                              361         /* I1 = ip ptr, I2 = pings sent, I3 = ping responses, I4 = pings received   */
+#define NX_TRACE_ICMP_PING                                  362         /* I1 = ip ptr, I2 = ip_address, I3 = data ptr, I4 = data size              */
+#define NX_TRACE_IGMP_ENABLE                                363         /* I1 = ip ptr                                                              */
+#define NX_TRACE_IGMP_INFO_GET                              364         /* I1 = ip ptr, I2 = reports sent, I3 = queries received, I4 = groups joined*/
+#define NX_TRACE_IGMP_LOOPBACK_DISABLE                      365         /* I1 = ip ptr                                                              */
+#define NX_TRACE_IGMP_LOOPBACK_ENABLE                       366         /* I1 = ip ptr                                                              */
+#define NX_TRACE_IGMP_MULTICAST_JOIN                        367         /* I1 = ip ptr, I2 = group address                                          */
+#define NX_TRACE_IGMP_MULTICAST_LEAVE                       368         /* I1 = ip ptr, I2 = group_address                                          */
+#define NX_TRACE_IP_ADDRESS_CHANGE_NOTIFY                   369         /* I1 = ip ptr, I2 = ip address change notify, I3 = additional info         */
+#define NX_TRACE_IP_ADDRESS_GET                             370         /* I1 = ip ptr, I2 = ip address, I3 = network_mask                          */
+#define NX_TRACE_IP_ADDRESS_SET                             371         /* I1 = ip ptr, I2 = ip address, I3 = network_mask                          */
+#define NX_TRACE_IP_CREATE                                  372         /* I1 = ip ptr, I2 = ip address, I3 = network mask, I4 = default_pool       */
+#define NX_TRACE_IP_DELETE                                  373         /* I1 = ip ptr                                                              */
+#define NX_TRACE_IP_DRIVER_DIRECT_COMMAND                   374         /* I1 = ip ptr, I2 = command, I3 = return value                             */
+#define NX_TRACE_IP_FORWARDING_DISABLE                      375         /* I1 = ip ptr                                                              */
+#define NX_TRACE_IP_FORWARDING_ENABLE                       376         /* I1 = ip ptr                                                              */
+#define NX_TRACE_IP_FRAGMENT_DISABLE                        377         /* I1 = ip ptr                                                              */
+#define NX_TRACE_IP_FRAGMENT_ENABLE                         378         /* I1 = ip ptr                                                              */
+#define NX_TRACE_IP_GATEWAY_ADDRESS_SET                     379         /* I1 = ip ptr, I2 = gateway address                                        */
+#define NX_TRACE_IP_INFO_GET                                380         /* I1 = ip ptr, I2 = bytes sent, I3 = bytes received, I4 = packets dropped  */
+#define NX_TRACE_IP_RAW_PACKET_DISABLE                      381         /* I1 = ip ptr                                                              */
+#define NX_TRACE_IP_RAW_PACKET_ENABLE                       382         /* I1 = ip ptr                                                              */
+#define NX_TRACE_IP_RAW_PACKET_RECEIVE                      383         /* I1 = ip ptr, I2 = packet ptr, I3 = wait option                           */
+#define NX_TRACE_IP_RAW_PACKET_SEND                         384         /* I1 = ip ptr, I2 = packet ptr, I3 = destination ip, I4 = type of service  */
+#define NX_TRACE_IP_STATUS_CHECK                            385         /* I1 = ip ptr, I2 = needed status, I3 = actual status, I4 = wait option    */
+#define NX_TRACE_PACKET_ALLOCATE                            386         /* I1 = pool ptr, I2 = packet ptr, I3 = packet type, I4 = available packets */
+#define NX_TRACE_PACKET_COPY                                387         /* I1 = packet ptr, I2 = new packet ptr, I3 = pool ptr, I4 = wait option    */
+#define NX_TRACE_PACKET_DATA_APPEND                         388         /* I1 = packet ptr, I2 = data start, I3 = data size, I4 = pool ptr          */
+#define NX_TRACE_PACKET_DATA_RETRIEVE                       389         /* I1 = packet ptr, I2 = buffer start, I3 = bytes copied                    */
+#define NX_TRACE_PACKET_LENGTH_GET                          390         /* I1 = packet ptr, I2 = length                                             */
+#define NX_TRACE_PACKET_POOL_CREATE                         391         /* I1 = pool ptr, I2 = payload size, I3 = memory ptr, I4 = memory_size      */
+#define NX_TRACE_PACKET_POOL_DELETE                         392         /* I1 = pool ptr                                                            */
+#define NX_TRACE_PACKET_POOL_INFO_GET                       393         /* I1 = pool ptr, I2 = total_packets, I3 = free packets, I4 = empty requests*/
+#define NX_TRACE_PACKET_RELEASE                             394         /* I1 = packet ptr, I2 = packet status, I3 = available packets              */
+#define NX_TRACE_PACKET_TRANSMIT_RELEASE                    395         /* I1 = packet ptr, I2 = packet status, I3 = available packets              */
+#define NX_TRACE_RARP_DISABLE                               396         /* I1 = ip ptr                                                              */
+#define NX_TRACE_RARP_ENABLE                                397         /* I1 = ip ptr                                                              */
+#define NX_TRACE_RARP_INFO_GET                              398         /* I1 = ip ptr, I2 = requests sent, I3 = responses received, I4 = invalids  */
+#define NX_TRACE_SYSTEM_INITIALIZE                          399         /* none                                                                     */
+#define NX_TRACE_TCP_CLIENT_SOCKET_BIND                     400         /* I1 = ip ptr, I2 = socket ptr, I3 = port, I4 = wait option                */
+#define NX_TRACE_TCP_CLIENT_SOCKET_CONNECT                  401         /* I1 = ip ptr, I2 = socket ptr, I3 = server ip, I4 = server port           */
+#define NX_TRACE_TCP_CLIENT_SOCKET_PORT_GET                 402         /* I1 = ip ptr, I2 = socket ptr, I3 = port                                  */
+#define NX_TRACE_TCP_CLIENT_SOCKET_UNBIND                   403         /* I1 = ip ptr, I2 = socket ptr                                             */
+#define NX_TRACE_TCP_ENABLE                                 404         /* I1 = ip ptr                                                              */
+#define NX_TRACE_TCP_FREE_PORT_FIND                         405         /* I1 = ip ptr, I2 = port, I3 = free port                                   */
+#define NX_TRACE_TCP_INFO_GET                               406         /* I1 = ip ptr, I2 = bytes sent, I3 = bytes received, I4 = invalid packets  */
+#define NX_TRACE_TCP_SERVER_SOCKET_ACCEPT                   407         /* I1 = ip ptr, I2 = socket ptr, I3 = wait option, I4 = socket state        */
+#define NX_TRACE_TCP_SERVER_SOCKET_LISTEN                   408         /* I1 = ip ptr, I2 = port, I3 = socket ptr, I4 = listen queue size          */
+#define NX_TRACE_TCP_SERVER_SOCKET_RELISTEN                 409         /* I1 = ip ptr, I2 = port, I3 = socket ptr, I4 = socket state               */
+#define NX_TRACE_TCP_SERVER_SOCKET_UNACCEPT                 410         /* I1 = ip ptr, I2 = socket ptr, I3 = socket state                          */
+#define NX_TRACE_TCP_SERVER_SOCKET_UNLISTEN                 411         /* I1 = ip ptr, I2 = port                                                   */
+#define NX_TRACE_TCP_SOCKET_CREATE                          412         /* I1 = ip ptr, I2 = socket ptr, I3 = type of service, I4 = window size     */
+#define NX_TRACE_TCP_SOCKET_DELETE                          413         /* I1 = ip ptr, I2 = socket ptr, I3 = socket state                          */
+#define NX_TRACE_TCP_SOCKET_DISCONNECT                      414         /* I1 = ip ptr, I2 = socket ptr, I3 = wait option, I4 = socket state        */
+#define NX_TRACE_TCP_SOCKET_INFO_GET                        415         /* I1 = ip ptr, I2 = socket ptr, I3 = bytes sent, I4 = bytes received       */
+#define NX_TRACE_TCP_SOCKET_MSS_GET                         416         /* I1 = ip ptr, I2 = socket ptr, I3 = mss, I4 = socket state                */
+#define NX_TRACE_TCP_SOCKET_MSS_PEER_GET                    417         /* I1 = ip ptr, I2 = socket ptr, I3 = peer_mss, I4 = socket state           */
+#define NX_TRACE_TCP_SOCKET_MSS_SET                         418         /* I1 = ip ptr, I2 = socket ptr, I3 = mss, I4 socket state                  */
+#define NX_TRACE_TCP_SOCKET_RECEIVE                         419         /* I1 = socket ptr, I2 = packet ptr, I3 = length, I4 = rx sequence          */
+#define NX_TRACE_TCP_SOCKET_RECEIVE_NOTIFY                  420         /* I1 = ip ptr, I2 = socket ptr, I3 = receive notify                        */
+#define NX_TRACE_TCP_SOCKET_SEND                            421         /* I1 = socket ptr, I2 = packet ptr, I3 = length, I4 = tx sequence          */
+#define NX_TRACE_TCP_SOCKET_STATE_WAIT                      422         /* I1 = ip ptr, I2 = socket ptr, I3 = desired state, I4 = previous state    */
+#define NX_TRACE_TCP_SOCKET_TRANSMIT_CONFIGURE              423         /* I1 = ip ptr, I2 = socket ptr, I3 = queue depth, I4 = timeout             */
+#define NX_TRACE_UDP_ENABLE                                 424         /* I1 = ip ptr                                                              */
+#define NX_TRACE_UDP_FREE_PORT_FIND                         425         /* I1 = ip ptr, I2 = port, I3 = free port                                   */
+#define NX_TRACE_UDP_INFO_GET                               426         /* I1 = ip ptr, I2 = bytes sent, I3 = bytes received, I4 = invalid packets  */
+#define NX_TRACE_UDP_SOCKET_BIND                            427         /* I1 = ip ptr, I2 = socket ptr, I3 = port, I4 = wait option                */
+#define NX_TRACE_UDP_SOCKET_CHECKSUM_DISABLE                428         /* I1 = ip ptr, I2 = socket ptr                                             */
+#define NX_TRACE_UDP_SOCKET_CHECKSUM_ENABLE                 429         /* I1 = ip ptr, I2 = socket ptr                                             */
+#define NX_TRACE_UDP_SOCKET_CREATE                          430         /* I1 = ip ptr, I2 = socket ptr, I3 = type of service, I4 = queue maximum   */
+#define NX_TRACE_UDP_SOCKET_DELETE                          431         /* I1 = ip ptr, I2 = socket ptr                                             */
+#define NX_TRACE_UDP_SOCKET_INFO_GET                        432         /* I1 = ip ptr, I2 = socket ptr, I3 = bytes sent, I4 = bytes received       */
+#define NX_TRACE_UDP_SOCKET_PORT_GET                        433         /* I1 = ip ptr, I2 = socket ptr, I3 = port                                  */
+#define NX_TRACE_UDP_SOCKET_RECEIVE                         434         /* I1 = ip ptr, I2 = socket ptr, I3 = packet ptr, I4 = packet size          */
+#define NX_TRACE_UDP_SOCKET_RECEIVE_NOTIFY                  435         /* I1 = ip ptr, I2 = socket ptr, I3 = receive notify                        */
+#define NX_TRACE_UDP_SOCKET_SEND                            436         /* I1 = socket ptr, I2 = packet ptr, I3 = packet size, I4 = ip address      */
+#define NX_TRACE_UDP_SOCKET_UNBIND                          437         /* I1 = ip ptr, I2 = socket ptr, I3 = port                                  */
+#define NX_TRACE_UDP_SOURCE_EXTRACT                         438         /* I1 = packet ptr, I2 = ip address, I3 = port                              */
+#define NX_TRACE_IP_INTERFACE_ATTACH                        439         /* I1 = ip ptr, I2 = ip address, I3 = interface index                       */
+#define NX_TRACE_UDP_SOCKET_BYTES_AVAILABLE                 440         /* I1 = ip ptr, I2 = socket ptr, I3 = bytes available                       */
+#define NX_TRACE_IP_STATIC_ROUTE_ENABLE                     441         /* I1 = ip_ptr,                                                             */
+#define NX_TRACE_IP_STATIC_ROUTE_DISABLE                    442         /* I1 = ip_ptr,                                                             */
+#define NX_TRACE_IP_STATIC_ROUTE_ADD                        443         /* I1 = ip_ptr, I2 = network_address, I3 = net_mask, I4 = next_hop          */
+#define NX_TRACE_IP_STATIC_ROUTE_DELETE                     444         /* I1 = ip_ptr, I2 = network_address, I3 = net_mask                         */
+#define NX_TRACE_TCP_SOCKET_PEER_INFO_GET                   445         /* I1 = socket ptr, I2 = network_address, I3 = port                         */
+#define NX_TRACE_TCP_SOCKET_WINDOW_UPDATE_NOTIFY_SET        446         /* I1 = socket ptr,                                                         */
+#define NX_TRACE_UDP_SOCKET_INTERFACE_SET                   447         /* I1 = socket_ptr, I2 = interface_index,                                   */
+#define NX_TRACE_UDP_SOCKET_INTERFACE_CLEAR                 448         /* I1 = socket_ptr,                                                         */
+#define NX_TRACE_IP_INTERFACE_INFO_GET                      449         /* I1 = ip_ptr, I2 = ip_address, I3 = mtu_size, I4 = interface_index        */
+#define NX_TRACE_PACKET_DATA_EXTRACT_OFFSET                 450         /* I1 = packet_ptr, I2 = buffer_length, I3 = bytes_copied,                  */
+
+
+#endif
+
+
+#ifndef NXD_TRACE_ICMP_ENABLE
+#define NXD_TRACE_ICMP_ENABLE                               470         /* I1 = ip ptr                                                              */
+#define NX_TRACE_ICMP_PING6                                 471         /* I1 = ip ptr, I2 = ip_address, I3 = data ptr, I4 = data size              */
+#define NXD_TRACE_UDP_SOURCE_EXTRACT                        472         /* I1 = packet ptr, I2 = IP Version (4 or 6), I3 = ip address, I4 = port    */
+#define NXD_TRACE_UDP_SOCKET_SET_INTERFACE                  473         /* I1 = udp_socket_ptr, I2 = interface_id                                   */
+#define NXD_TRACE_TCP_SOCKET_SET_INTERFACE                  474         /* I1 = tcp_socket_ptr, I2 = interface_id                                   */
+#define NXD_TRACE_UDP_SOCKET_SEND                           475         /* I1 = socket ptr, I2 = packet ptr, I3 = packet size, I4 = ip address      */
+#define NXD_TRACE_ND_CACHE_DELETE                           476         /* I1 = dest_ip                                                             */
+#define NXD_TRACE_ND_CACHE_ENTRY_SET                        477         /* I1 = IP address, I2 = physical msw, I3 = physical lsw                    */
+#define NX_TRACE_ND_CACHE_IP_ADDRESS_FIND                   478         /* I1 = ip_ptr, I2 = IP address, I3 = physical msw, I4 = physical lsw       */
+#define NXD_TRACE_ND_CACHE_INVALIDATE                       479         /* I1 = ip_ptr                                                              */
+#define NXD_TRACE_IPV6_GLOBAL_ADDRESS_GET                   480         /* (Obsolete) I1 = ip_ptr, I2 = IP address lsw, I3 = prefix length          */
+#define NXD_TRACE_IPV6_GLOBAL_ADDRESS_SET                   481         /* (Obsolete) I1 = ip_ptr, I2 = IP address lsw, I3 = prefix length          */
+#define NX_TRACE_IPSTATIC_ROUTE_ADD                         482         /* I1 = ip_ptr, I2 = network address, I3 = net_mask, I4 = next hop address  */
+#define NX_TRACE_IP_STATIC_ROUTING_ENABLE                   483         /* I1 = ip_ptr                                                              */
+#define NX_TRACE_IP_STATIC_ROUTING_DISABLE                  484         /* I1 = ip_ptr                                                              */
+#define NX_TRACE_IPV6_ENABLE                                485         /* I1 = ip_ptr                                                              */
+#define NXD_TRACE_IPV6_RAW_PACKET_SEND                      486         /* I1 = ip_ptr, I2 = ip address lsw, I3 = protocol, I4 = packet_ptr         */
+#define NXD_TRACE_IP_RAW_PACKET_SEND                        487         /* I1 = ip_ptr, I2 = ip address lsw, I3 = type of serveice, I4 = packet_ptr */
+#define NXD_TRACE_IPV6_LINKLOCAL_ADDRESS_GET                488         /* (Obsolete) I1 = ip_ptr, I2 = IP address lsw                              */
+#define NXD_TRACE_IPV6_LINKLOCAL_ADDRESS_SET                489         /* (Obsolete) I1 = ip_ptr, I2 = IP address lsw, I3 = prefix length          */
+#define NXD_TRACE_IPV6_INITIATE_DAD_PROCESS                 490         /* I1 = ip_ptr                                                              */
+#define NXD_TRACE_IPV6_DEFAULT_ROUTER_ADD                   491         /* I1 = ip_ptr, I2 = router addr lsw, I3 = router lifetime                  */
+#define NXD_TRACE_IPV6_DEFAULT_ROUTER_DELETE                492         /* I1 = ip_ptr, I2 = router addr lsw,                                       */
+#define NXD_TRACE_IPV6_INTERFACE_ADDRESS_GET                493         /* I1 = ip_ptr, I2 = IP address lsw,I3 = prefix length,I4 = interface_index */
+#define NXD_TRACE_IPV6_INTERFACE_ADDRESS_SET                494         /* I1 = ip_ptr, I2 = IP address lsw,I3 = prefix length,I4 = interface_index */
+#define NXD_TRACE_TCP_SOCKET_PEER_INFO_GET                  495         /* I1 = socket_ptr, I2 = Peer IP address, I3 = peer_port                    */
+#define NXD_TRACE_IP_MAX_PAYLOAD_SIZE_FIND                  496         /* I1 = src address, I2 = dst address,I3 = payload length,I4 = start offset */
+#define NX_TRACE_IPV6_DISABLE                               497         /* I1 = ip_ptr                                                              */
+#define NXD_TRACE_IPV6_ADDRESS_CHANGE_NOTIFY                498         /* I1 = ip_ptr, I2 = notify_callback                                        */
+#define NXD_TRACE_IPV6_STATELESS_ADDRESS_AUTOCONFIG_ENABLE  499         /* I1 = ip_ptr, I2 = interface_index                                        */
+#define NXD_TRACE_IPV6_STATELESS_ADDRESS_AUTOCONFIG_DISABLE 500         /* I1 = ip_ptr, I2 = interface_index                                        */
+#define NXD_TRACE_IP_RAW_PACKET_FILTER_SET                  501         /* I1 = ip_ptr, I2 = raw_pcket_filter                                       */
+#endif
+
+/* Map the trace macros to internal NetX versions so we can get interrupt protection.  */
+
+#ifdef NX_SOURCE_CODE
+
+#define NX_TRACE_OBJECT_REGISTER(t, p, n, a, b)             _nx_trace_object_register(t, (VOID *)p, (CHAR *)n, (ULONG)a, (ULONG)b)
+#define NX_TRACE_OBJECT_UNREGISTER(o)                       _nx_trace_object_unregister((VOID *)o)
+#define NX_TRACE_IN_LINE_INSERT(i, a, b, c, d, f, g, h)     _nx_trace_event_insert((ULONG)i, (ULONG)a, (ULONG)b, (ULONG)c, (ULONG)d, (ULONG)f, g, h)
+#define NX_TRACE_EVENT_UPDATE(e, t, i, a, b, c, d)          _nx_trace_event_update((TX_TRACE_BUFFER_ENTRY *)e, (ULONG)t, (ULONG)i, (ULONG)a, (ULONG)b, (ULONG)c, (ULONG)d)
+#endif
+/* Define NetX trace prototypes.  */
+
+VOID _nx_trace_object_register(UCHAR object_type, VOID *object_ptr, CHAR *object_name, ULONG parameter_1, ULONG parameter_2);
+VOID _nx_trace_object_unregister(VOID *object_ptr);
+VOID _nx_trace_event_insert(ULONG event_id, ULONG info_field_1, ULONG info_field_2, ULONG info_field_3, ULONG info_field_4, ULONG filter, TX_TRACE_BUFFER_ENTRY **current_event, ULONG *current_timestamp);
+VOID _nx_trace_event_update(TX_TRACE_BUFFER_ENTRY *event, ULONG timestamp, ULONG event_id, ULONG info_field_1, ULONG info_field_2, ULONG info_field_3, ULONG info_field_4);
+
+#else
+#define NX_TRACE_OBJECT_REGISTER(t, p, n, a, b)
+#define NX_TRACE_OBJECT_UNREGISTER(o)
+#define NX_TRACE_IN_LINE_INSERT(i, a, b, c, d, f, g, h)
+#define NX_TRACE_EVENT_UPDATE(e, t, i, a, b, c, d)
+#endif
+
+/* If NX_PACKET_HEADER_PAD is defined, make sure NX_PACKET_HEADER_PAD_SIZE is also defined.  The default is 1, for backward compatibility. */
+#ifdef NX_PACKET_HEADER_PAD
+#ifndef NX_PACKET_HEADER_PAD_SIZE
+#define NX_PACKET_HEADER_PAD_SIZE                1
+#endif /* NX_PACKET_HEADER_PAD_SIZE */
+#endif /* NX_PACKET_HEADER_PAD */
+
+/* If NX_PACKET_ALIGNMENT is defined, packet header and payload are aligned automatically to the value specified
+   in the symbol. The default is to align packet payload area to ULONG. */
+#ifndef NX_PACKET_ALIGNMENT
+#define NX_PACKET_ALIGNMENT                      sizeof(ULONG)
+#endif /* NX_PACKET_ALIGNMENT */
+
+
+/* Define basic constants for the NetX TCP/IP Stack.  */
+#define AZURE_RTOS_NETXDUO
+#define NETXDUO_MAJOR_VERSION                    6
+#define NETXDUO_MINOR_VERSION                    4
+#define NETXDUO_PATCH_VERSION                    0
+
+/* Define the following symbols for backward compatibility */
+#define EL_PRODUCT_NETXDUO
+#define __PRODUCT_NETXDUO__
+#define __NETXDUO_MAJOR_VERSION__                NETXDUO_MAJOR_VERSION
+#define __NETXDUO_MINOR_VERSION__                NETXDUO_MINOR_VERSION
+
+/* API input parameters and general constants.  */
+#define NX_NO_WAIT                               0
+#define NX_WAIT_FOREVER                          ((ULONG)0xFFFFFFFF)
+#define NX_TRUE                                  1
+#define NX_FALSE                                 0
+#define NX_NULL                                  0
+#define NX_FOREVER                               1
+#define NX_INIT_PACKET_ID                        1
+#ifndef NX_MAX_PORT
+#define NX_MAX_PORT                              0xFFFF
+#endif /* NX_MAX_PORT */
+#define NX_LOWER_16_MASK                         ((ULONG)0x0000FFFF)
+#define NX_CARRY_BIT                             ((ULONG)0x10000)
+#define NX_SHIFT_BY_16                           16
+#define NX_TCP_CLIENT                            1
+#define NX_TCP_SERVER                            2
+#define NX_ANY_PORT                              0
+#ifndef NX_SEARCH_PORT_START
+#define NX_SEARCH_PORT_START                     0xC000 /* Free port search start UDP/TCP */
+#endif /* NX_SEARCH_PORT_START */
+
+#ifndef NX_PHYSICAL_HEADER
+#define NX_PHYSICAL_HEADER                       16    /* Maximum physical header        */
+#endif
+
+#ifndef NX_PHYSICAL_TRAILER
+#define NX_PHYSICAL_TRAILER                      4     /* Maximum physical trailer       */
+#endif
+
+/* Specify th wait interval, in seconds. */
+#ifndef NX_PATH_MTU_INCREASE_WAIT_INTERVAL
+#define NX_PATH_MTU_INCREASE_WAIT_INTERVAL       600
+#endif
+
+#define NX_PATH_MTU_INCREASE_WAIT_INTERVAL_TICKS (NX_PATH_MTU_INCREASE_WAIT_INTERVAL * NX_IP_PERIODIC_RATE)
+
+/* By default IPv6 is enabled. */
+#ifndef NX_DISABLE_IPV6
+#ifndef FEATURE_NX_IPV6
+#define FEATURE_NX_IPV6
+#endif /* FEATURE_NX_IPV6 */
+#endif /* NX_DISABLE_IPV6 */
+
+/* Remove the IPv6 component if NX_DISABLE_IPV6 is defined. */
+#ifdef NX_DISABLE_IPV6
+#ifdef FEATURE_NX_IPV6
+#undef FEATURE_NX_IPV6
+#endif /* FEATURE_NX_IPV6 */
+#endif /* NX_DISABLE_IPV6 */
+
+#ifdef NX_IPSEC_ENABLE
+
+/* Define the IPsec header size.  The space reserved here is good for ESP/AH header and possiblly IPv4/v6 header in tunnel mode. */
+#ifdef FEATURE_NX_IPV6
+#define NX_IPSEC_MAX_HEADER_SIZE    (((NX_CRYPTO_MAX_IV_SIZE_IN_BITS + NX_CRYPTO_AUTHENTICATION_ICV_TRUNC_BITS + 7) / 8) + 16 + 40)
+#else /* !FEATURE_NX_IPV6 */
+#define NX_IPSEC_MAX_HEADER_SIZE    (((NX_CRYPTO_MAX_IV_SIZE_IN_BITS + NX_CRYPTO_AUTHENTICATION_ICV_TRUNC_BITS + 7) / 8) + 12 + 20)
+#endif /* FEATURE_NX_IPV6 */
+
+#else /* !NX_IPSEC_ENABLE */
+#define NX_IPSEC_MAX_HEADER_SIZE    0
+#endif /* NX_IPSEC_ENABLE */
+
+#ifndef NX_IPV6_HOST_ID_LENGTH
+#define NX_IPV6_HOST_ID_LENGTH      64
+#endif /* NX_IPV6_HOST_ID_LENGTH */
+
+#define NX_IPv4_PACKET              (NX_PHYSICAL_HEADER + 20)   /* 20 bytes of IP header          */
+#define NX_IPv4_TCP_PACKET          (NX_IPv4_PACKET + 20)       /* IP header plus 20 bytes        */
+#define NX_IPv4_UDP_PACKET          (NX_IPv4_PACKET + 8)        /* IP header plus 8 bytes         */
+#define NX_IPv4_ICMP_PACKET         (NX_IPv4_PACKET)
+#define NX_IPv4_IGMP_PACKET         (NX_IPv4_PACKET)
+
+#define NX_IPv6_PACKET              (NX_PHYSICAL_HEADER + 40)   /* 40 bytes of basic IPv6 Header  */
+#define NX_IPv6_UDP_PACKET          (NX_IPv6_PACKET + 8)        /* IPv6 header plus 8 bytes       */
+#define NX_IPv6_TCP_PACKET          (NX_IPv6_PACKET + 20)       /* IPv6 header plus 20 bytes      */
+#define NX_IPv6_ICMP_PACKET         (NX_IPv6_PACKET)
+#define NX_RECEIVE_PACKET           0                           /* This is for driver receive     */
+
+
+#ifdef FEATURE_NX_IPV6
+/* For systems with IPv6 enabled, the payload offset defaults to IPv6 header size. */
+#define NX_IP_PACKET                NX_IPv6_PACKET
+#define NX_TCP_PACKET               (NX_IPv6_TCP_PACKET + NX_IPSEC_MAX_HEADER_SIZE)
+#define NX_UDP_PACKET               (NX_IPv6_UDP_PACKET + NX_IPSEC_MAX_HEADER_SIZE)
+#define NX_ICMP_PACKET              (NX_IPv6_ICMP_PACKET + NX_IPSEC_MAX_HEADER_SIZE)
+#else
+/* Define payload offset to IPv4 header size if IPv6 is not defined.  */
+#define NX_IP_PACKET                NX_IPv4_PACKET
+#define NX_TCP_PACKET               (NX_IPv4_TCP_PACKET + NX_IPSEC_MAX_HEADER_SIZE)
+#define NX_UDP_PACKET               (NX_IPv4_UDP_PACKET + NX_IPSEC_MAX_HEADER_SIZE)
+#define NX_ICMP_PACKET              (NX_IPv4_ICMP_PACKET + NX_IPSEC_MAX_HEADER_SIZE)
+#endif /* FEATURE_NX_IPV6 */
+#define NX_IGMP_PACKET              NX_IPv4_IGMP_PACKET
+
+
+/* Define the ARP update rate, in terms of IP periodic intervals.  This can be defined on the
+   command line as well.  */
+
+#ifndef NX_ARP_UPDATE_RATE
+#define NX_ARP_UPDATE_RATE          10
+#endif
+
+
+/* Define the ARP entry expiration rate, in terms of IP periodic intervals.  This can be defined on the
+   command line as well.   A value of 0 disables ARP entry expiration, and is the default.  */
+
+#ifndef NX_ARP_EXPIRATION_RATE
+#define NX_ARP_EXPIRATION_RATE      0
+#endif
+
+
+/* Define the ARP maximum retry constant that specifies the maximum number of ARP requests that will be sent
+   without receiving an ARP response.  Once this limit is reached, the ARP attempt is abandoned and
+   any queued packet is released.  */
+
+#ifndef NX_ARP_MAXIMUM_RETRIES
+#define NX_ARP_MAXIMUM_RETRIES      18
+#endif
+
+
+/* Define the maximum number of packets that can be queued while waiting for ARP resolution of an
+   IP address.  */
+
+#ifndef NX_ARP_MAX_QUEUE_DEPTH
+#define NX_ARP_MAX_QUEUE_DEPTH      4
+#endif
+
+
+/* Define the maximum time of IP reassembly.  */
+#ifndef NX_IP_MAX_REASSEMBLY_TIME
+
+/* Define the maximum time of IPv4 reassembly. RFC791, Section3.2, page27.  */
+#ifndef NX_IPV4_MAX_REASSEMBLY_TIME
+#define NX_IPV4_MAX_REASSEMBLY_TIME 15
+#endif
+
+/* Define the maximum time of IPv6 reassembly. RFC2460, Section4.5, page22.  */
+#ifndef NX_IPV6_MAX_REASSEMBLY_TIME
+#define NX_IPV6_MAX_REASSEMBLY_TIME 60
+#endif
+
+#else /* NX_IP_MAX_REASSEMBLY_TIME */
+
+/* Define the maximum time of IP reassembly.  */
+#define NX_IPV4_MAX_REASSEMBLY_TIME NX_IP_MAX_REASSEMBLY_TIME
+#define NX_IPV6_MAX_REASSEMBLY_TIME NX_IP_MAX_REASSEMBLY_TIME
+
+#endif /* NX_IP_MAX_REASSEMBLY_TIME */
+
+
+/* Define the maximum number of the packets that can be queued for raw receive. */
+#ifndef NX_IP_RAW_MAX_QUEUE_DEPTH
+#define NX_IP_RAW_MAX_QUEUE_DEPTH   20
+#endif
+
+#ifndef NX_IP_ROUTING_TABLE_SIZE
+#define NX_IP_ROUTING_TABLE_SIZE    8
+#endif /* NX_IP_ROUTING_TABLE_SIZE */
+
+/* For backward compatibility, map the smbol NX_RAW_PACKET_FILTER_ENABLE to
+   NX_ENABLE_IP_RAW_PACKET_FILTER. */
+#ifdef NX_RAW_PACKET_FILTER_ENABLE
+#ifndef NX_ENABLE_IP_RAW_PACKET_FILTER
+#define NX_ENABLE_IP_RAW_PACKET_FILTER
+#endif /* NX_ENABLE_IP_RAW_PACKET_FILTER */
+#endif /* NX_RAW_PACKET_FILTER_ENABLE */
+
+/* For backward compatibility, map the symbol NXDUO_DISABLE_ICMPV6_REDIRECT_PROCESS
+   to NX_DISABLE_ICMPV6_REDIRECT_PROCESS.   */
+#ifdef NXDUO_DISABLE_ICMPV6_REDIRECT_PROCESS
+#ifndef NX_DISABLE_ICMPV6_REDIRECT_PROCESS
+#define NX_DISABLE_ICMPV6_REDIRECT_PROCESS
+#endif /* NX_DISABLE_ICMPV6_REDIRECT_PROCESS */
+#endif /* NXDUO_DISABLE_ICMPV6_REDIRECT_PROCESS */
+
+/* For backward compatibility, convert map NXDUO_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS to NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS */
+#ifdef NXDUO_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS
+#ifndef NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS
+#define NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS
+#endif /* NX_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS */
+#endif /* NXDUO_DISABLE_ICMPV6_ROUTER_ADVERTISEMENT_PROCESS */
+
+/* For backward compatibility, convert map NXDUO_DISABLE_ICMPV6_ROUTER_SOLICITATION to NX_DISABLE_ICMPV6_ROUTER_SOLICITATION */
+#ifdef NXDUO_DISABLE_ICMPV6_ROUTER_SOLICITATION
+#ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
+#define NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
+#endif /* NX_DISABLE_ICMPV6_ROUTER_SOLICITATION */
+#endif /* NXDUO_DISABLE_ICMPV6_ROUTER_SOLICITATION */
+
+/* For backward compatibility, convert map NXDUO_DISABLE_ICMPV6_ERROR_MESSAGE to NX_DISABLE_ICMPV6_ERROR_MESSAGE */
+#ifdef NXDUO_DISABLE_ICMPV6_ERROR_MESSAGE
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+#define NX_DISABLE_ICMPV6_ERROR_MESSAGE
+#endif /* NX_DISABLE_ICMPV6_ERROR_MESSAGE */
+#endif /* NXDUO_DISABLE_ICMPV6_ERROR_MESSAGE */
+
+/* For backward compatibility, convert map NXDUO_DISABLE_DAD to NX_DISABLE_IPV6_DAD */
+#ifdef NXDUO_DISABLE_DAD
+#ifndef NX_DISABLE_IPV6_DAD
+#define NX_DISABLE_IPV6_DAD
+#endif /* NX_DISABLE_IPV6_DAD */
+#endif /* NXDUO_DISABLE_DAD */
+
+/* For backward compatibility, convert map NX_IPV6_ADDRESS_CHANGE_NOTIFY_ENABLE to NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
+#ifdef NX_IPV6_ADDRESS_CHANGE_NOTIFY_ENABLE
+#ifndef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
+#define NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
+#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
+#endif /* NX_IPV6_ADDRESS_CHANGE_NOTIFY_ENABLE */
+
+/* For backward compatibility, convert map NX_IPV6_DISABLE_PURGE_UNUSED_CACHE_ENTRIES to NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES */
+#ifdef NX_IPV6_DISABLE_PURGE_UNUSED_CACHE_ENTRIES
+#ifndef NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES
+#define NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES
+#endif /* NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES */
+#endif /* NX_IPV6_DISABLE_PURGE_UNUSED_CACHE_ENTRIES */
+
+/* For backward compatibility, convert map NX_IPV6_MULTICAST_ENABLE to NX_ENABLE_IPV6_MULTICAST */
+#ifdef NX_IPV6_MULTICAST_ENABLE
+#ifndef NX_ENABLE_IPV6_MULTICAST
+#define NX_ENABLE_IPV6_MULTICAST
+#endif /* NX_ENABLE_IPV6_MULTICAST */
+#endif /* NX_IPV6_MULTICAST_ENABLE */
+
+/* Define the size of the IPv6 destination table. */
+/* For backward compatibility, convert map NX_DESTINATION_TABLE_SIZE and NXDUO_DESTINATION_TABLE_SIZE to NX_IPV6_DESTINATION_TABLE_SIZE */
+#ifdef NX_DESTINATION_TABLE_SIZE
+#define NX_IPV6_DESTINATION_TABLE_SIZE  NX_DESTINATION_TABLE_SIZE
+#endif /* NX_DESTINATION_TABLE_SIZE */
+
+#ifdef NXDUO_DESTINATION_TABLE_SIZE
+#define NX_IPV6_DESTINATION_TABLE_SIZE  NXDUO_DESTINATION_TABLE_SIZE
+#endif /* NXDUO_DESTINATION_TABLE_SIZE */
+
+#ifndef NX_IPV6_DESTINATION_TABLE_SIZE
+#define NX_IPV6_DESTINATION_TABLE_SIZE  8
+#ifndef NX_DESTINATION_TABLE_SIZE
+#define NX_DESTINATION_TABLE_SIZE       NX_IPV6_DESTINATION_TABLE_SIZE
+#endif /* NX_DESTINATION_TABLE_SIZE */
+#ifndef NXDUO_DESTINATION_TABLE_SIZE
+#define NXDUO_DESTINATION_TABLE_SIZE    NX_IPV6_DESTINATION_TABLE_SIZE
+#endif /* NXDUO_DESTINATION_TABLE_SIZE */
+#endif /* NX_IPV6_DESTINATION_TABLE_SIZE */
+
+/* Define the size of the IPv6 ND cache table. */
+#ifndef NX_IPV6_NEIGHBOR_CACHE_SIZE
+#define NX_IPV6_NEIGHBOR_CACHE_SIZE     16
+#endif /* NX_IPV6_NEIGHBOR_CACHE_SIZE */
+
+/* Define the maximum ICMPv6 Duplicate Address Detect Transmit .  */
+/* For backward compatibility, convert map NX_DUP_ADDR_DETECT_TRANSMITS and NXDUO_DUP_ADDR_DETECT_TRANSMITS to NX_IPV6_DAD_TRANSMITS */
+#ifdef NX_DUP_ADDR_DETECT_TRANSMITS
+#define NX_IPV6_DAD_TRANSMITS           NX_DUP_ADDR_DETECT_TRANSMITS
+#endif /* NX_DUP_ADDR_DETECT_TRANSMITS */
+
+#ifdef NXDUO_DUP_ADDR_DETECT_TRANSMITS
+#define NX_IPV6_DAD_TRANSMITS           NXDUO_DUP_ADDR_DETECT_TRANSMITS
+#endif /* NXDUO_DUP_ADDR_DETECT_TRANSMITS */
+
+#ifndef NX_IPV6_DAD_TRANSMITS
+#define NX_IPV6_DAD_TRANSMITS           3
+#ifndef NX_DUP_ADDR_DETECT_TRANSMITS
+#define NX_DUP_ADDR_DETECT_TRANSMITS    NX_IPV6_DAD_TRANSMITS
+#endif /* NX_DUP_ADDR_DETECT_TRANSMITS */
+#ifndef NXDUO_DUP_ADDR_DETECT_TRANSMITS
+#define NXDUO_DUP_ADDR_DETECT_TRANSMITS NX_IPV6_DAD_TRANSMITS
+#endif /* NXDUO_DUP_ADDR_DETECT_TRANSMITS */
+#endif /* NX_IPV6_DAD_TRANSMITS */
+
+/* For backward compatibility, convert map NX_ARP_DISABLE_AUTO_ARP_ENTRY to NX_DISABLE_ARP_AUTO_ENTRY. */
+#ifdef NX_ARP_DISABLE_AUTO_ARP_ENTRY
+#ifndef NX_DISABLE_ARP_AUTO_ENTRY
+#define NX_DISABLE_ARP_AUTO_ENTRY
+#endif /* NX_DISABLE_ARP_AUTO_ENTRY */
+#endif /* NX_ARP_DISABLE_AUTO_ARP_ENTRY */
+
+/* For backward compatibility, convert map NX_TCP_ENABLE_KEEPALIVE to NX_ENABLE_TCP_KEEPALIVE. */
+#ifdef NX_TCP_ENABLE_KEEPALIVE
+#ifndef NX_ENABLE_TCP_KEEPALIVE
+#define NX_ENABLE_TCP_KEEPALIVE
+#endif /* NX_ENABLE_TCP_KEEPALIVE */
+#endif /* NX_TCP_ENABLE_KEEPALIVE */
+
+/* For backward compatibility, convert map NX_TCP_ENABLE_WINDOW_SCALING to NX_ENABLE_TCP_WINDOW_SCALING. */
+#ifdef NX_TCP_ENABLE_WINDOW_SCALING
+#ifndef NX_ENABLE_TCP_WINDOW_SCALING
+#define NX_ENABLE_TCP_WINDOW_SCALING
+#endif /* NX_ENABLE_TCP_WINDOW_SCALING */
+#endif /* NX_TCP_ENABLE_WINDOW_SCALING */
+
+/* For backward compatibility, convert map NX_TCP_ENABLE_MSS_CHECK to NX_ENABLE_TCP_MSS_CHECK. */
+#ifdef NX_TCP_ENABLE_MSS_CHECK
+#ifndef NX_ENABLE_TCP_MSS_CHECK
+#define NX_ENABLE_TCP_MSS_CHECK
+#endif /* NX_ENABLE_TCP_MSS_CHECK */
+#endif /* NX_TCP_ENABLE_MSS_CHECK */
+
+/* For backward compatibility, convert map NX_DUAL_PACKET_POOL_ENABLE to NX_ENABLE_DUAL_PACKET_POOL. */
+#ifdef NX_DUAL_PACKET_POOL_ENABLE
+#ifndef NX_ENABLE_DUAL_PACKET_POOL
+#define NX_ENABLE_DUAL_PACKET_POOL
+#endif /* NX_ENABLE_DUAL_PACKET_POOL. */
+#endif /* NX_DUAL_PACKET_POOL_ENABLE */
+
+/* For backward compatibility, convert map NX_ENABLE_FEATURE_LOW_WATERMARK to NX_ENABLE_LOW_WATERMARK. */
+#ifdef NX_ENABLE_FEATURE_LOW_WATERMARK
+#ifndef NX_ENABLE_LOW_WATERMARK
+#define NX_ENABLE_LOW_WATERMARK
+#endif /* NX_ENABLE_LOW_WATERMARK */
+#endif /* NX_ENABLE_FEATURE_LOW_WATERMARK */
+
+#ifdef NX_DISABLE_ICMP_RX_CHECKSUM
+#ifndef NX_DISABLE_ICMPV4_RX_CHECKSUM
+#define NX_DISABLE_ICMPV4_RX_CHECKSUM
+#endif
+#ifndef NX_DISABLE_ICMPV6_RX_CHECKSUM
+#define NX_DISABLE_ICMPV6_RX_CHECKSUM
+#endif
+#endif /* NX_DISABLE_ICMP_RX_CHECKSUM */
+
+#ifdef NX_DISABLE_ICMP_TX_CHECKSUM
+#ifndef NX_DISABLE_ICMPV4_TX_CHECKSUM
+#define NX_DISABLE_ICMPV4_TX_CHECKSUM
+#endif
+#ifndef NX_DISABLE_ICMPV6_TX_CHECKSUM
+#define NX_DISABLE_ICMPV6_TX_CHECKSUM
+#endif
+#endif /* NX_DISABLE_ICMP_TX_CHECKSUM */
+
+/* For backward compatibility, convert map NX_DISABLE_ICMPv4_RX_CHECKSUM to NX_DISABLE_ICMPV4_RX_CHECKSUM. */
+#ifdef NX_DISABLE_ICMPv4_RX_CHECKSUM
+#ifndef NX_DISABLE_ICMPV4_RX_CHECKSUM
+#define NX_DISABLE_ICMPV4_RX_CHECKSUM
+#endif /* NX_DISABLE_ICMPV4_RX_CHECKSUM */
+#endif /* NX_DISABLE_ICMPv4_RX_CHECKSUM */
+
+/* For backward compatibility, convert map NX_DISABLE_ICMPv4_TX_CHECKSUM to NX_DISABLE_ICMPV4_TX_CHECKSUM. */
+#ifdef NX_DISABLE_ICMPv4_TX_CHECKSUM
+#ifndef NX_DISABLE_ICMPV4_TX_CHECKSUM
+#define NX_DISABLE_ICMPV4_TX_CHECKSUM
+#endif /* NX_DISABLE_ICMPV4_TX_CHECKSUM */
+#endif /* NX_DISABLE_ICMPv4_TX_CHECKSUM */
+
+/* For backward compatibility, convert map NX_DISABLE_ICMPv6_RX_CHECKSUM to NX_DISABLE_ICMPV6_RX_CHECKSUM. */
+#ifdef NX_DISABLE_ICMPv6_RX_CHECKSUM
+#ifndef NX_DISABLE_ICMPV6_RX_CHECKSUM
+#define NX_DISABLE_ICMPV6_RX_CHECKSUM
+#endif /* NX_DISABLE_ICMPV6_RX_CHECKSUM */
+#endif /* NX_DISABLE_ICMPv6_RX_CHECKSUM */
+
+/* For backward compatibility, convert map NX_DISABLE_ICMPv6_TX_CHECKSUM to NX_DISABLE_ICMPV6_TX_CHECKSUM. */
+#ifdef NX_DISABLE_ICMPv6_TX_CHECKSUM
+#ifndef NX_DISABLE_ICMPV6_TX_CHECKSUM
+#define NX_DISABLE_ICMPV6_TX_CHECKSUM
+#endif /* NX_DISABLE_ICMPV6_TX_CHECKSUM */
+#endif /* NX_DISABLE_ICMPv6_TX_CHECKSUM */
+
+
+
+#ifdef NX_ENABLE_EXTENDED_NOTIFY_SUPPORT
+#ifdef NX_DISABLE_EXTENDED_NOTIFY_SUPPORT
+#undef NX_DISABLE_EXTENDED_NOTIFY_SUPPORT
+#endif /* NX_ENABLE_EXTENDED_NOTIFY_SUPPORT */
+#else
+#define NX_DISABLE_EXTENDED_NOTIFY_SUPPORT
+#endif /* !NX_ENABLE_EXTENDED_NOTIFY_SUPPORT */
+
+/* Define the IPv4 fragment options.  */
+
+#define NX_FRAGMENT_OKAY                       ((ULONG)0x00000000)
+#define NX_DONT_FRAGMENT                       ((ULONG)0x00004000)
+#define NX_MORE_FRAGMENTS                      ((ULONG)0x00002000)
+#define NX_FRAG_OFFSET_MASK                    ((ULONG)0x00001FFF)
+
+
+/* Define the IPv4 Type Of Service constants.  These will be supplied to the
+   IPv4 output packet routine.  */
+
+#define NX_IP_NORMAL                           ((ULONG)0x00000000) /* Normal IP delivery                     */
+#define NX_IP_MIN_DELAY                        ((ULONG)0x00100000) /* Minimum Delay delivery                 */
+#define NX_IP_MAX_DATA                         ((ULONG)0x00080000) /* Maximum Throughput delivery            */
+#define NX_IP_MAX_RELIABLE                     ((ULONG)0x00040000) /* Maximum Reliable delivery              */
+#define NX_IP_MIN_COST                         ((ULONG)0x00020000) /* Minimum Cost deliver                   */
+#define NX_IP_TOS_MASK                         ((ULONG)0x00FF0000) /* Type of Service Mask                   */
+
+
+/* Define the IPv4 length mask.   */
+
+#define NX_IP_PACKET_SIZE_MASK                 ((ULONG)0x0000FFFF) /* Mask for isolating the IP packet length */
+
+
+/* Define the IPv4 default time to live.  */
+
+#define NX_IP_TIME_TO_LIVE                     ((ULONG)0x00000080) /* Default packet time to live            */
+#define NX_IP_TIME_TO_LIVE_MASK                ((ULONG)0xFF000000) /* Mask for isolating the time to live    */
+#define NX_IP_TIME_TO_LIVE_SHIFT               24                  /* Number of bits to shift left           */
+
+
+
+
+/* Define IPv6 protocol types.  These types are used in the
+   "next header" field in IPv6 header and optional headers. */
+#define NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP     0
+#define NX_PROTOCOL_ICMP                       1
+#define NX_PROTOCOL_IGMP                       2
+#define NX_PROTOCOL_IPV4                       4   /* IP-in-IP encapsulation */
+#define NX_PROTOCOL_TCP                        6
+#define NX_PROTOCOL_UDP                        17
+#define NX_PROTOCOL_IPV6                       41  /* IP-in-IP encapsulation */
+#define NX_PROTOCOL_NEXT_HEADER_ROUTING        43
+#define NX_PROTOCOL_NEXT_HEADER_FRAGMENT       44
+#define NX_PROTOCOL_NEXT_HEADER_ENCAP_SECURITY 50
+#define NX_PROTOCOL_NEXT_HEADER_AUTHENTICATION 51
+#define NX_PROTOCOL_ICMPV6                     58
+#define NX_PROTOCOL_NO_NEXT_HEADER             59
+#define NX_PROTOCOL_NEXT_HEADER_DESTINATION    60
+#define NX_PROTOCOL_NEXT_HEADER_MOBILE         135
+
+/* Define the type of Protocol in this IPv6 packet.  */
+/* Note that these values can be directly mapped to the protocol field in an IPv4 header. */
+#define NX_IP_ICMP                             ((ULONG)0x00010000) /* ICMP Protocol Type                     */
+#define NX_IP_IGMP                             ((ULONG)0x00020000) /* IGMP Protocol Type                     */
+#define NX_IP_TCP                              ((ULONG)0x00060000) /* TCP Protocol Type                      */
+#define NX_IP_UDP                              ((ULONG)0x00110000) /* UDP Protocol Type                      */
+#define NX_IP_ESP                              ((ULONG)0x00320000) /* ESP Protocol Type                      */
+#define NX_IP_AH                               ((ULONG)0x00330000) /* UDP Protocol Type                      */
+#define NX_IP_PROTOCOL_MASK                    ((ULONG)0x00FF0000) /* Protocol Type mask                     */
+
+
+/* Define IPv4 address type masks and values.  These will determine the net id and
+   host id fields of the supplied IPv4 address.  */
+
+#define NX_IP_CLASS_A_MASK                     ((ULONG)0x80000000) /* Define mask for class A IP addresses   */
+#define NX_IP_CLASS_A_TYPE                     ((ULONG)0x00000000) /* Define class A address type            */
+#define NX_IP_CLASS_A_NETID                    ((ULONG)0x7F000000) /* Define class A network ID mask         */
+#define NX_IP_CLASS_A_HOSTID                   ((ULONG)0x00FFFFFF) /* Define class A host ID mask            */
+
+#define NX_IP_CLASS_B_MASK                     ((ULONG)0xC0000000) /* Define mask for class B IP addresses   */
+#define NX_IP_CLASS_B_TYPE                     ((ULONG)0x80000000) /* Define class B address type            */
+#define NX_IP_CLASS_B_NETID                    ((ULONG)0x3FFF0000) /* Define class B network ID mask         */
+#define NX_IP_CLASS_B_HOSTID                   ((ULONG)0x0000FFFF) /* Define class B host ID mask            */
+
+#define NX_IP_CLASS_C_MASK                     ((ULONG)0xE0000000) /* Define mask for class C IP addresses   */
+#define NX_IP_CLASS_C_TYPE                     ((ULONG)0xC0000000) /* Define class C address type            */
+#define NX_IP_CLASS_C_NETID                    ((ULONG)0x1FFFFF00) /* Define class C network ID mask         */
+#define NX_IP_CLASS_C_HOSTID                   ((ULONG)0x000000FF) /* Define class C host ID mask            */
+
+#define NX_IP_CLASS_D_MASK                     ((ULONG)0xF0000000) /* Define mask for class D IP addresses   */
+#define NX_IP_CLASS_D_TYPE                     ((ULONG)0xE0000000) /* Define class D address type            */
+#define NX_IP_CLASS_D_GROUP                    ((ULONG)0x0FFFFFFF) /* Define class D group ID mask           */
+#define NX_IP_CLASS_D_HOSTID                   ((ULONG)0x00000000) /* Define class D host ID mask N/A        */
+
+#define NX_IP_LIMITED_BROADCAST                ((ULONG)0xFFFFFFFF) /* Limited broadcast address (local net)  */
+#define NX_IP_LOOPBACK_FIRST                   ((ULONG)0x7F000000) /* First loopback address 127.0.0.0       */
+#define NX_IP_LOOPBACK_LAST                    ((ULONG)0x7FFFFFFF) /* Last loopback address  127.255.255.255 */
+
+#define NX_IP_MULTICAST_UPPER                  ((ULONG)0x00000100) /* Upper two bytes of multicast Ethernet  */
+#define NX_IP_MULTICAST_LOWER                  ((ULONG)0x5E000000) /* Lower 23 bits of address are from IP   */
+#define NX_IP_MULTICAST_MASK                   ((ULONG)0x007FFFFF) /* Mask to pickup the lower 23 bits of IP */
+
+
+/* Define the constants that determine how big the hash table is for destination IP
+   addresses.  The value must be a power of two, so subtracting one gives us
+   the mask.  */
+
+#define NX_ROUTE_TABLE_SIZE                    32
+#define NX_ROUTE_TABLE_MASK                    (NX_ROUTE_TABLE_SIZE - 1)
+
+/* By default use 0xFF when sending raw packet.  */
+#ifndef NX_IP_RAW
+#define NX_IP_RAW                              0x00FF0000
+#endif /* NX_IP_RAW */
+
+/*
+ * NX_ROUTE_TABLE_SIZE|MASK are used for ARP table. So we define NX_ARP_TABLE_SIZE|MASK so the
+ *    macro names are more descriptive.
+ *
+ * NX_ROUTE_TABLE_SIZE and NX_ROUTE_TABLE_MASK will be deprecated in future releases.
+ */
+#define NX_ARP_TABLE_SIZE                      NX_ROUTE_TABLE_SIZE
+#define NX_ARP_TABLE_MASK                      (NX_ARP_TABLE_SIZE - 1)
+
+
+
+#ifdef FEATURE_NX_IPV6
+/* Define IPv6 address state.  These states are defined in RFC 2462. */
+
+#define NX_IPV6_ADDR_STATE_UNKNOWN             0x00
+#define NX_IPV6_ADDR_STATE_TENTATIVE           0x01
+#define NX_IPV6_ADDR_STATE_PREFERRED           0x02
+#define NX_IPV6_ADDR_STATE_DEPRECATED          0x03
+#define NX_IPV6_ADDR_STATE_VALID               0x04
+
+
+
+/* Define the size of the IPv6 Default Router Table. */
+#ifndef NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE
+#define NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE      8
+#endif /* NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE */
+
+/* Define the size of the IPv6 prefix table. */
+#ifndef NX_IPV6_PREFIX_LIST_TABLE_SIZE
+#define NX_IPV6_PREFIX_LIST_TABLE_SIZE         8
+#endif /* NX_IPV6_PREFIX_LIST_TABLE_SIZE */
+
+/* Flags for the IPv6 default router table status field. */
+#define NX_IPV6_ROUTE_TYPE_NOT_ROUTER          0x00
+#define NX_IPV6_ROUTE_TYPE_SOLICITATED         0x01
+#define NX_IPV6_ROUTE_TYPE_UNSOLICITATED       0x02
+#define NX_IPV6_ROUTE_TYPE_STATIC              0x04
+#define NX_IPV6_ROUTE_TYPE_DEFAULT             0x40
+#define NX_IPV6_ROUTE_TYPE_VALID               0x80
+
+#define NX_IPV6_ADDRESS_NOT_CONFIGURED         0
+#define NX_IPV6_ADDRESS_MANUAL_CONFIG          1
+#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
+#define NX_IPV6_ADDRESS_STATELESS_AUTO_CONFIG  2
+#define NX_IPV6_ADDRESS_STATEFUL_AUTO_CONFIG   3
+#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
+#define NX_IPV6_ADDRESS_BASED_ON_INTERFACE     4
+#define NX_IPV6_ADDRESS_MANUAL_DELETE          5
+#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
+#define NX_IPV6_ADDRESS_LIFETIME_EXPIRED       6
+#define NX_IPV6_ADDRESS_DAD_SUCCESSFUL         7
+#define NX_IPV6_ADDRESS_DAD_FAILURE            8
+#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
+
+
+
+/* Define the maximum number of packets that can be queued while waiting for Neighbor Discovery
+   to resolution of an IPv6 address.  */
+#ifndef NX_ND_MAX_QUEUE_DEPTH
+#define NX_ND_MAX_QUEUE_DEPTH                  4
+#endif
+
+/* Define the ND cache entry structure. */
+typedef struct ND_CACHE_ENTRY_STRUCT
+{
+
+    /* Neighbor IP address. */
+    ULONG nx_nd_cache_dest_ip[4];
+
+    /* Corresponding LLA.   */
+    UCHAR nx_nd_cache_mac_addr[6];
+
+    /* Padding.  Reserved for future use. */
+    /*lint -esym(768,ND_CACHE_ENTRY_STRUCT::nx_nd_cache_reserved1) suppress member not referenced. It is reserved for future use. */
+    UCHAR nx_nd_cache_reserved1;
+
+    /* Padding.  Reserved for future use. */
+    /*lint -esym(768,ND_CACHE_ENTRY_STRUCT::nx_nd_cache_reserved2) suppress member not referenced. It is reserved for future use. */
+    UCHAR nx_nd_cache_reserved2;
+
+    /* Number of Solicitation it needs to send before timing out. */
+    UCHAR nx_nd_cache_num_solicit;
+
+    /* Entry Status, such as INCOMPLETE, REACHABLE, and so on. */
+    UCHAR nx_nd_cache_nd_status;
+
+    /* Number of out going packets waiting for this entry to be resolved. */
+    UCHAR nx_nd_cache_packet_waiting_queue_length;
+
+    /* Whether or not this entry is statically configured. */
+    UCHAR nx_nd_cache_is_static;
+
+    /* Timeout value. */
+    ULONG nx_nd_cache_timer_tick;
+
+    /* Interface through which the destination can be reached. */
+    struct NX_INTERFACE_STRUCT *nx_nd_cache_interface_ptr;
+
+    /* Link to the default router table, if this neighbor is a router. */
+    struct NX_IPV6_DEFAULT_ROUTER_ENTRY_STRUCT *nx_nd_cache_is_router;
+
+    /*
+     * Queue head and queue tail of the out going packets.
+     * This queue is used for keeping outgoing packets while the stack is
+     * resolving the target link layer address.
+     */
+    struct NX_PACKET_STRUCT *nx_nd_cache_packet_waiting_head;
+    struct NX_PACKET_STRUCT *nx_nd_cache_packet_waiting_tail;
+
+    /*
+     * Local interface associated with this neighbor entry. If outoing_address is known
+     * outgoing packets shall be sent using this address.
+     */
+    struct NXD_IPV6_ADDRESS_STRUCT *nx_nd_cache_outgoing_address;
+} ND_CACHE_ENTRY;
+
+/* Define the destination table entry type. */
+typedef struct NX_IPV6_DESTINATION_ENTRY_STRUCT
+{
+    /* Flag indicates whether or not the entry is valid. */
+    ULONG nx_ipv6_destination_entry_valid;
+
+    /* Destination IP address. */
+    ULONG nx_ipv6_destination_entry_destination_address[4];
+
+    /* Next hop address.  Next hop could be the host, if it
+       is on the local network, or a router. */
+    ULONG nx_ipv6_destination_entry_next_hop[4];
+
+    /* Cross link to the next hop entry in the ND cache. */
+    ND_CACHE_ENTRY *nx_ipv6_destination_entry_nd_entry;
+
+#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
+
+    /* Maximum transmission size for this destination. */
+    ULONG nx_ipv6_destination_entry_path_mtu;
+
+    /* MTU Timeout value. */
+    ULONG nx_ipv6_destination_entry_MTU_timer_tick;
+#endif
+} NX_IPV6_DESTINATION_ENTRY;
+
+/* Define data structure for IPv6 prefix table. */
+typedef struct NX_IPV6_PREFIX_ENTRY_STRUCT
+{
+    /* Network IPv6 prefix address, in host byte order. */
+    ULONG nx_ipv6_prefix_entry_network_address[4];
+
+    /* Number of valid bits in the prefix. */
+    ULONG nx_ipv6_prefix_entry_prefix_length;
+
+    /* Valid life time, in seconds. */
+    ULONG nx_ipv6_prefix_entry_valid_lifetime;
+
+    /* Pointer to the previous entry. */
+    struct NX_IPV6_PREFIX_ENTRY_STRUCT *nx_ipv6_prefix_entry_prev;
+
+    /* Pointer to the next entry. */
+    struct NX_IPV6_PREFIX_ENTRY_STRUCT *nx_ipv6_prefix_entry_next;
+} NX_IPV6_PREFIX_ENTRY;
+
+
+/* Define data structure for IPv6 default router table. */
+typedef struct NX_IPV6_DEFAULT_ROUTER_ENTRY_STRUCT
+{
+    /* route type */
+    UCHAR nx_ipv6_default_router_entry_flag;
+
+    /* Reserved for future expansion. */
+    /*lint -esym(768,NX_IPV6_DEFAULT_ROUTER_ENTRY_STRUCT::nx_ipv6_default_router_entry_reserved) suppress member not referenced. It is reserved for future use. */
+    UCHAR nx_ipv6_default_router_entry_reserved;
+
+    /* Router Life Time, in seconds, host-byte order. */
+    USHORT nx_ipv6_default_router_entry_life_time;
+
+    /* Router interface address. */
+    ULONG nx_ipv6_default_router_entry_router_address[4];
+
+    /* Router interface index.  */
+    struct NX_INTERFACE_STRUCT *nx_ipv6_default_router_entry_interface_ptr;
+
+    /* Point to the corresonding neighbor cache entry. */
+    ND_CACHE_ENTRY *nx_ipv6_default_router_entry_neighbor_cache_ptr;
+} NX_IPV6_DEFAULT_ROUTER_ENTRY;
+
+#endif /* FEATURE_NX_IPV6 */
+/* Define the constants that determine how big the hash table is for UDP ports.  The
+   value must be a power of two, so subtracting one gives us the mask.  */
+
+#define NX_UDP_PORT_TABLE_SIZE                     32
+#define NX_UDP_PORT_TABLE_MASK                     (NX_UDP_PORT_TABLE_SIZE - 1)
+
+
+/* Define the constants that determine how big the hash table is for TCP ports.  The
+   value must be a power of two, so subtracting one gives us the mask.  */
+
+#define NX_TCP_PORT_TABLE_SIZE                     32
+#define NX_TCP_PORT_TABLE_MASK                     (NX_TCP_PORT_TABLE_SIZE - 1)
+
+
+/* Define the maximum number of multicast groups the system can support.  This might
+   be further limited by the underlying physical hardware.  */
+
+#ifndef NX_MAX_MULTICAST_GROUPS
+#define NX_MAX_MULTICAST_GROUPS                    7
+#endif
+
+/* The following symbol defines the number of IPv6 addresses in the system.
+   A typical system shall have 2 IPv6 addresses: one linklocal address and one global address.  */
+
+
+/* Define the maximum number of internal server resources for TCP connections.  Server
+   connections require a listen control structure.  */
+
+#ifndef NX_MAX_LISTEN_REQUESTS
+#define NX_MAX_LISTEN_REQUESTS                     10
+#endif
+
+/* Define the max length of username and password for HTTP Proxy authentication.  */
+
+/* Define the max length of username.  */
+#ifndef NX_HTTP_PROXY_MAX_USERNAME
+#define NX_HTTP_PROXY_MAX_USERNAME                 20
+#endif
+
+/* Define the max length of password.  */
+#ifndef NX_HTTP_PROXY_MAX_PASSWORD
+#define NX_HTTP_PROXY_MAX_PASSWORD                 20
+#endif
+
+/* NX_HTTP_PROXY_MAX_AUTHENTICATION is the max length of base64 of "name:password", 
+   1 bytes for an extra conversion if needed, 2 bytes for pad if needed, 1 byte for null terminator and four byte alignment. */
+#define NX_HTTP_PROXY_MAX_AUTHENTICATION           (((((NX_HTTP_PROXY_MAX_USERNAME + NX_HTTP_PROXY_MAX_PASSWORD  + 1 ) * 4 / 3) + 1 + 2 + 1) / 4 + 1) * 4)
+
+
+/* Define the IP status checking/return bits.  */
+
+#define NX_IP_INITIALIZE_DONE                      ((ULONG)0x0001)
+#define NX_IP_ADDRESS_RESOLVED                     ((ULONG)0x0002)
+#define NX_IP_LINK_ENABLED                         ((ULONG)0x0004)
+#define NX_IP_ARP_ENABLED                          ((ULONG)0x0008)
+#define NX_IP_UDP_ENABLED                          ((ULONG)0x0010)
+#define NX_IP_TCP_ENABLED                          ((ULONG)0x0020)
+#define NX_IP_IGMP_ENABLED                         ((ULONG)0x0040)
+#define NX_IP_RARP_COMPLETE                        ((ULONG)0x0080)
+#define NX_IP_INTERFACE_LINK_ENABLED               ((ULONG)0x0100)
+
+/* Define various states in the TCP connection state machine.  */
+
+#define NX_TCP_CLOSED                              1  /* Connection is closed state   */
+#define NX_TCP_LISTEN_STATE                        2  /* Server listen state          */
+#define NX_TCP_SYN_SENT                            3  /* SYN sent state               */
+#define NX_TCP_SYN_RECEIVED                        4  /* SYN received state           */
+#define NX_TCP_ESTABLISHED                         5  /* Connection established state */
+#define NX_TCP_CLOSE_WAIT                          6  /* Close Wait state             */
+#define NX_TCP_FIN_WAIT_1                          7  /* Finished Wait 1 state        */
+#define NX_TCP_FIN_WAIT_2                          8  /* Finished Wait 2 state        */
+#define NX_TCP_CLOSING                             9  /* Closing state                */
+#define NX_TCP_TIMED_WAIT                          10 /* Timed wait state             */
+#define NX_TCP_LAST_ACK                            11 /* Last ACK state               */
+
+
+/* API return values.  */
+
+#define NX_SUCCESS                                 0x00
+#define NX_NO_PACKET                               0x01
+#define NX_UNDERFLOW                               0x02
+#define NX_OVERFLOW                                0x03
+#define NX_NO_MAPPING                              0x04
+#define NX_DELETED                                 0x05
+#define NX_POOL_ERROR                              0x06
+#define NX_PTR_ERROR                               0x07
+#define NX_WAIT_ERROR                              0x08
+#define NX_SIZE_ERROR                              0x09
+#define NX_OPTION_ERROR                            0x0a
+#define NX_DELETE_ERROR                            0x10
+#define NX_CALLER_ERROR                            0x11
+#define NX_INVALID_PACKET                          0x12
+#define NX_INVALID_SOCKET                          0x13
+#define NX_NOT_ENABLED                             0x14
+#define NX_ALREADY_ENABLED                         0x15
+#define NX_ENTRY_NOT_FOUND                         0x16
+#define NX_NO_MORE_ENTRIES                         0x17
+#define NX_ARP_TIMER_ERROR                         0x18
+#define NX_RESERVED_CODE0                          0x19
+#define NX_WAIT_ABORTED                            0x1A
+#define NX_IP_INTERNAL_ERROR                       0x20
+#define NX_IP_ADDRESS_ERROR                        0x21
+#define NX_ALREADY_BOUND                           0x22
+#define NX_PORT_UNAVAILABLE                        0x23
+#define NX_NOT_BOUND                               0x24
+#define NX_RESERVED_CODE1                          0x25
+#define NX_SOCKET_UNBOUND                          0x26
+#define NX_NOT_CREATED                             0x27
+#define NX_SOCKETS_BOUND                           0x28
+#define NX_NO_RESPONSE                             0x29
+#define NX_POOL_DELETED                            0x30
+#define NX_ALREADY_RELEASED                        0x31
+#define NX_RESERVED_CODE2                          0x32
+#define NX_MAX_LISTEN                              0x33
+#define NX_DUPLICATE_LISTEN                        0x34
+#define NX_NOT_CLOSED                              0x35
+#define NX_NOT_LISTEN_STATE                        0x36
+#define NX_IN_PROGRESS                             0x37
+#define NX_NOT_CONNECTED                           0x38
+#define NX_WINDOW_OVERFLOW                         0x39
+#define NX_ALREADY_SUSPENDED                       0x40
+#define NX_DISCONNECT_FAILED                       0x41
+#define NX_STILL_BOUND                             0x42
+#define NX_NOT_SUCCESSFUL                          0x43
+#define NX_UNHANDLED_COMMAND                       0x44
+#define NX_NO_FREE_PORTS                           0x45
+#define NX_INVALID_PORT                            0x46
+#define NX_INVALID_RELISTEN                        0x47
+#define NX_CONNECTION_PENDING                      0x48
+#define NX_TX_QUEUE_DEPTH                          0x49
+#define NX_NOT_IMPLEMENTED                         0x4A
+#define NX_NOT_SUPPORTED                           0x4B
+#define NX_INVALID_INTERFACE                       0x4C
+#define NX_INVALID_PARAMETERS                      0x4D
+#define NX_NOT_FOUND                               0x4E
+#define NX_CANNOT_START                            0x4F
+#define NX_NO_INTERFACE_ADDRESS                    0x50
+#define NX_INVALID_MTU_DATA                        0x51
+#define NX_DUPLICATED_ENTRY                        0x52
+#define NX_PACKET_OFFSET_ERROR                     0x53
+#define NX_OPTION_HEADER_ERROR                     0x54
+#define NX_CONTINUE                                0x55
+#define NX_TCPIP_OFFLOAD_ERROR                     0x56
+
+/* Define Link Driver constants.  */
+
+#define NX_LINK_PACKET_SEND                        0
+#define NX_LINK_INITIALIZE                         1
+#define NX_LINK_ENABLE                             2
+#define NX_LINK_DISABLE                            3
+#define NX_LINK_PACKET_BROADCAST                   4
+#define NX_LINK_ARP_SEND                           5
+#define NX_LINK_ARP_RESPONSE_SEND                  6
+#define NX_LINK_RARP_SEND                          7
+#define NX_LINK_MULTICAST_JOIN                     8
+#define NX_LINK_MULTICAST_LEAVE                    9
+#define NX_LINK_GET_STATUS                         10
+#define NX_LINK_GET_SPEED                          11
+#define NX_LINK_GET_DUPLEX_TYPE                    12
+#define NX_LINK_GET_ERROR_COUNT                    13
+#define NX_LINK_GET_RX_COUNT                       14
+#define NX_LINK_GET_TX_COUNT                       15
+#define NX_LINK_GET_ALLOC_ERRORS                   16
+#define NX_LINK_UNINITIALIZE                       17
+#define NX_LINK_DEFERRED_PROCESSING                18
+#define NX_LINK_INTERFACE_ATTACH                   19
+#define NX_LINK_SET_PHYSICAL_ADDRESS               20
+#define NX_INTERFACE_CAPABILITY_GET                21
+#define NX_INTERFACE_CAPABILITY_SET                22
+#define NX_LINK_INTERFACE_DETACH                   23
+#define NX_LINK_FACTORY_ADDRESS_GET                24
+#define NX_LINK_RX_ENABLE                          25
+#define NX_LINK_RX_DISABLE                         26
+#define NX_LINK_6LOWPAN_COMMAND                    27 /* 6LowPAN driver command, the sub command see nx_6lowpan.h.  */
+#define NX_LINK_GET_INTERFACE_TYPE                 28
+#define NX_LINK_RAW_PACKET_SEND                    29
+
+#define NX_LINK_USER_COMMAND                       50 /* Values after this value are reserved for application.  */
+
+
+/* Define operations for TCP/IP offload callback functions.  */
+#define NX_TCPIP_OFFLOAD_TCP_CLIENT_SOCKET_CONNECT  0
+#define NX_TCPIP_OFFLOAD_TCP_SERVER_SOCKET_LISTEN   1
+#define NX_TCPIP_OFFLOAD_TCP_SERVER_SOCKET_ACCEPT   2
+#define NX_TCPIP_OFFLOAD_TCP_SERVER_SOCKET_UNLISTEN 3
+#define NX_TCPIP_OFFLOAD_TCP_SOCKET_DISCONNECT      4
+#define NX_TCPIP_OFFLOAD_TCP_SOCKET_SEND            5
+#define NX_TCPIP_OFFLOAD_UDP_SOCKET_BIND            6
+#define NX_TCPIP_OFFLOAD_UDP_SOCKET_UNBIND          7
+#define NX_TCPIP_OFFLOAD_UDP_SOCKET_SEND            8
+
+
+/* Define Link Driver Capability Flags.  */
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+#define NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM   0x00000001
+#define NX_INTERFACE_CAPABILITY_IPV4_RX_CHECKSUM   0x00000002
+#define NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM    0x00000004
+#define NX_INTERFACE_CAPABILITY_TCP_RX_CHECKSUM    0x00000008
+#define NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM    0x00000010
+#define NX_INTERFACE_CAPABILITY_UDP_RX_CHECKSUM    0x00000020
+#define NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM 0x00000040
+#define NX_INTERFACE_CAPABILITY_ICMPV4_RX_CHECKSUM 0x00000080
+#define NX_INTERFACE_CAPABILITY_ICMPV6_RX_CHECKSUM 0x00000100
+#define NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM 0x00000200
+#define NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM   0x00000400
+#define NX_INTERFACE_CAPABILITY_IGMP_RX_CHECKSUM   0x00000800
+#define NX_INTERFACE_CAPABILITY_PTP_TIMESTAMP      0x00001000
+#define NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD      0x00002000
+#define NX_INTERFACE_CAPABILITY_CHECKSUM_ALL       (NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM | \
+                                                    NX_INTERFACE_CAPABILITY_IPV4_RX_CHECKSUM | \
+                                                    NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM | \
+                                                    NX_INTERFACE_CAPABILITY_TCP_RX_CHECKSUM | \
+                                                    NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM | \
+                                                    NX_INTERFACE_CAPABILITY_UDP_RX_CHECKSUM | \
+                                                    NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM | \
+                                                    NX_INTERFACE_CAPABILITY_ICMPV4_RX_CHECKSUM | \
+                                                    NX_INTERFACE_CAPABILITY_ICMPV6_RX_CHECKSUM | \
+                                                    NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM | \
+                                                    NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM | \
+                                                    NX_INTERFACE_CAPABILITY_IGMP_RX_CHECKSUM)     
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+#define NX_IP_VERSION_V4                           0x4
+#define NX_IP_VERSION_V6                           0x6
+
+#if defined(FEATURE_NX_IPV6) && defined(NX_IPV6_STATELESS_AUTOCONFIG_CONTROL)
+#define NX_STATELESS_ADDRESS_AUTOCONFIG_ENABLED    0
+#define NX_STATELESS_ADDRESS_AUTOCONFIG_DISABLED   1
+#endif /* defined(FEATURE_NX_IPV6) && defined(NX_IPV6_STATELESS_AUTOCONFIG_CONTROL) */
+
+/* Define the macro for building IPv4 addresses.  */
+#define IP_ADDRESS(a, b, c, d)                     ((((ULONG)a) << 24) | (((ULONG)b) << 16) | (((ULONG)c) << 8) | ((ULONG)d))
+
+/* Define the direction of IP packet. */
+#ifdef NX_ENABLE_IP_PACKET_FILTER
+#define NX_IP_PACKET_IN                            0
+#define NX_IP_PACKET_OUT                           1
+#endif /* NX_ENABLE_IP_PACKET_FILTER */
+
+/* Define the interface type.  */
+#define NX_INTERFACE_TYPE_UNKNOWN                  0
+#define NX_INTERFACE_TYPE_OTHER                    1
+#define NX_INTERFACE_TYPE_ETHERNET                 2
+#define NX_INTERFACE_TYPE_WIFI                     3
+#define NX_INTERFACE_TYPE_CELLULAR                 4
+#define NX_INTERFACE_TYPE_BLUETOOTH                5
+#define NX_INTERFACE_TYPE_LORAWAN                  6
+#define NX_INTERFACE_TYPE_MAX                      7
+
+#ifdef NX_ENABLE_THREAD
+/* Define the packet type for Thread MLE.  */
+#define NX_PACKET_TYPE_THREAD_MLE                  0x01
+#endif /* NX_ENABLE_THREAD  */
+
+#define NX_VLAN_PRIORITY_INVALID                   0xFF
+#define NX_VLAN_PRIORITY_MAX                       0x07
+
+/* Define IPv4/v6 Address structure */
+typedef struct NXD_ADDRESS_STRUCT
+{
+    /* Flag indicating IP address format.  Valid values are:
+       NX_IP_VERSION_V4 and NX_IP_VERSION_V6.
+     */
+    ULONG nxd_ip_version;
+
+    /* Union that holds either IPv4 or IPv6 address. */
+    union
+    {
+
+#ifndef NX_DISABLE_IPV4
+        ULONG v4;
+#endif /* NX_DISABLE_IPV4 */
+#ifdef FEATURE_NX_IPV6
+        ULONG v6[4];
+#endif /* FEATURE_NX_IPV6 */
+    } nxd_ip_address;
+} NXD_ADDRESS;
+
+
+#ifdef NX_IPSEC_ENABLE
+/* Define the selector for IPSEC or TUNNEL. */
+typedef struct NX_ADDRESS_SELECTOR_STRUCT
+{
+    /* Define selector source, destination address. */
+    NXD_ADDRESS nx_selector_src_address_start;
+    NXD_ADDRESS nx_selector_src_address_end;
+    NXD_ADDRESS nx_selector_dst_address_start;
+    NXD_ADDRESS nx_selector_dst_address_end;
+} NX_ADDRESS_SELECTOR;
+
+#endif /* NX_IPSEC_ENABLE */
+
+
+/* Define the control block definitions for all system objects.  */
+
+
+/* Define the basic memory management packet structure.  This structure is
+   used to hold application data as well as internal control data.  */
+struct NX_PACKET_POOL_STRUCT;
+
+#ifdef NX_ENABLE_PACKET_DEBUG_INFO
+/* Define macro to record packet debug information.  */
+#define NX_PACKET_DEBUG(f,l,p)  {\
+        (p) -> nx_packet_debug_file=f;\
+        (p) -> nx_packet_debug_line=l;\
+        if (tx_thread_identify())                            \
+            (p) -> nx_packet_debug_thread = tx_thread_identify() -> tx_thread_name;                            \
+        else                            \
+            (p) -> nx_packet_debug_thread = "ISR";                            \
+                                }
+#else
+#define NX_PACKET_DEBUG(f, l, p)
+#endif /* NX_ENABLE_PACKET_DEBUG_INFO */
+
+typedef  struct NX_PACKET_STRUCT
+{
+
+    /* Define the pool this packet is associated with.  */
+    struct NX_PACKET_POOL_STRUCT
+                *nx_packet_pool_owner;
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+    /* Define the link to the chain (one or more) of packet extensions.  If this is NULL, there
+       are no packet extensions for this packet.  */
+    struct NX_PACKET_STRUCT
+                *nx_packet_next;
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+    /* Define the pointer to the first byte written closest to the beginning of the
+       buffer.  This is used to prepend information in front of the packet.  */
+    UCHAR       *nx_packet_prepend_ptr;
+
+    /* Define the pointer to the byte after the last character written in the buffer.  */
+    UCHAR       *nx_packet_append_ptr;
+
+    /* Define the packet data area start and end pointer.  These will be used to
+       mark the physical boundaries of the packet.  */
+    UCHAR       *nx_packet_data_start;
+    UCHAR       *nx_packet_data_end;
+
+    /* The above data are required by all packets. */
+    /* The following data are required by header packet when optimized packet is not disabled. */
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+    /* Define the link to the last packet (if any) in the chain.  This is used to append
+       information to the end without having to traverse the entire chain.  */
+    struct NX_PACKET_STRUCT
+                *nx_packet_last;
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+    /* Define the link that will be used to queue the packet.  */
+    struct NX_PACKET_STRUCT
+                *nx_packet_queue_next;
+
+    /* Union that holds either tcp_queue_next or fragment_next. */
+    union
+    {
+
+        /* Define the link that will be used to keep outgoing TCP packets queued
+           so they can be ACKed or re-sent.  */
+        struct NX_PACKET_STRUCT
+                *nx_packet_tcp_queue_next;
+
+#ifndef NX_DISABLE_FRAGMENTATION
+        /* Define the link to the next fragment.  This is only used in IP fragmentation
+           re-assembly.  */
+        struct NX_PACKET_STRUCT
+                *nx_packet_fragment_next;
+#endif /* NX_DISABLE_FRAGMENTATION */
+    } nx_packet_union_next;
+
+    /* Define the total packet length.  */
+    ULONG       nx_packet_length;
+
+#ifndef NX_DISABLE_FRAGMENTATION
+    ULONG       nx_packet_reassembly_time;  /* Time stamp for measuring the number of seconds a
+                                               packet is in the reassebmly logic.  Once a time
+                                               out value is reached packets of the same FRAG ID
+                                               are released. */
+#endif /* NX_DISABLE_FRAGMENTATION */
+
+#ifdef FEATURE_NX_IPV6
+    UCHAR       nx_packet_option_state;  /* Used by IPv6, indicating the current option
+                                            being processed. */
+    UCHAR       nx_packet_destination_header;
+    USHORT      nx_packet_option_offset;
+#endif /* FEATURE_NX_IPV6 */
+
+
+    /*
+       Tag the packet type. Valid values are either
+       NX_IP_VERSION_V4 or NX_IP_VERSION_V6.
+     */
+    UCHAR       nx_packet_ip_version;
+
+    /* RFC1122, Section3.2.1.5, Page32-33. RFC1122, Section4.2.2.15, Page90-91.  */
+    /* nx_packet_identical_copy is to track the IP ID field in the IP header
+       for the retransmitted TCP packet. The IP ID value should not change
+       if the TCP header for a retransmitted packet is not changed.
+
+       On retransmission, if the flag nx_packet_identical_copy is set, the same IP ID value is used for the retransmitted packet.
+       Otherwise the value in the IP ID field is updated with the latest ID value in the IP instance.
+     */
+    UCHAR       nx_packet_identical_copy;
+
+    /* Length of IP header including options. It is set for outgoing packet only. */
+    UCHAR       nx_packet_ip_header_length;
+
+#ifdef NX_ENABLE_VLAN
+    /* vlan priority */
+    UCHAR       nx_packet_vlan_priority;
+#else
+    /*lint -esym(768,NX_PACKET_STRUCT::nx_packet_reserved) suppress member not referenced. It is reserved for future use. */
+    UCHAR       nx_packet_reserved;
+#endif /* NX_ENABLE_VLAN */
+
+    /* Union that holds either IPv4 interface or IPv6 address. */
+    union
+    {
+
+        /* Define the interface from which the packet was received, or the interface to transmit to. */
+        struct NX_INTERFACE_STRUCT
+                *nx_packet_interface_ptr;
+
+        /* Point to the interface IPv6 address structure.  On transmit or receive path. */
+        struct NXD_IPV6_ADDRESS_STRUCT
+                *nx_packet_ipv6_address_ptr;
+    } nx_packet_address;
+
+#define nx_packet_ip_interface nx_packet_address.nx_packet_interface_ptr
+
+    /* Points to the beginning of IPv4/6 header.  This field is used for */
+    /* quick refernece to the IP header, in case there are optional headers. */
+    UCHAR       *nx_packet_ip_header;
+
+#ifdef NX_ENABLE_THREAD
+    /* Define the packet type for MLE.  */
+    UCHAR       nx_packet_type;
+
+    /* Define the received signal strength.  */
+    UCHAR       nx_packet_signal_strength;
+
+    /* It is reserved for future use.  */
+    UCHAR       nx_packet_thread_reserved[2];
+#endif /* NX_ENABLE_THREAD  */
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    /* Define the capability flag of hardware to be used by the packet. */
+    ULONG       nx_packet_interface_capability_flag;
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+#ifdef NX_IPSEC_ENABLE
+    VOID        *nx_packet_ipsec_sa_ptr;
+
+    /* Used in HW engine non-block mode. */
+    USHORT      nx_packet_ipsec_op;
+
+    /* Indicate the current protocol being processed. */
+    USHORT      nx_packet_ipsec_state;
+#endif /* NX_IPSEC_ENABLE */
+
+#ifdef NX_ENABLE_PACKET_DEBUG_INFO
+    /* Indicate the current thread that owns the packet. */
+    CHAR       *nx_packet_debug_thread;
+
+    /* Indicate the current file that is processing the packet. */
+    CHAR       *nx_packet_debug_file;
+
+    /* Indicate the current function that is processing the packet. */
+    ULONG       nx_packet_debug_line;
+#endif /* NX_ENABLE_PACKET_DEBUG_INFO */
+
+#ifdef NX_PACKET_HEADER_PAD
+
+    /* Define a pad word for 16-byte alignment, if necessary.  */
+    ULONG       nx_packet_packet_pad[NX_PACKET_HEADER_PAD_SIZE];
+#endif
+} NX_PACKET;
+
+
+/* Define the Packet Pool control block that will be used to manage each individual
+   packet pool.  */
+
+typedef struct NX_PACKET_POOL_STRUCT
+{
+
+    /* Define the block pool ID used for error checking.  */
+    ULONG       nx_packet_pool_id;
+
+    /* Define the packet pool's name.  */
+    CHAR       *nx_packet_pool_name;
+
+    /* Define the number of available memory packets in the pool.  */
+    ULONG       nx_packet_pool_available;
+
+    /* Save the initial number of blocks.  */
+    ULONG       nx_packet_pool_total;
+
+    /* Define statistics and error counters for this packet pool.  */
+    ULONG       nx_packet_pool_empty_requests;
+    ULONG       nx_packet_pool_empty_suspensions;
+    ULONG       nx_packet_pool_invalid_releases;
+
+    /* Define the head pointer of the available packet pool.  */
+    struct NX_PACKET_STRUCT    *nx_packet_pool_available_list;
+
+    /* Save the start address of the packet pool's memory area.  */
+    CHAR       *nx_packet_pool_start;
+
+    /* Save the packet pool's size in bytes.  */
+    ULONG       nx_packet_pool_size;
+
+    /* Save the individual packet payload size - rounded for alignment.  */
+    ULONG       nx_packet_pool_payload_size;
+
+    /* Define the packet pool suspension list head along with a count of
+       how many threads are suspended.  */
+    TX_THREAD  *nx_packet_pool_suspension_list;
+    ULONG       nx_packet_pool_suspended_count;
+
+    /* Define the created list next and previous pointers.  */
+    struct NX_PACKET_POOL_STRUCT
+               *nx_packet_pool_created_next,
+               *nx_packet_pool_created_previous;
+
+#ifdef NX_ENABLE_LOW_WATERMARK
+    /* Low watermark. */
+    UINT        nx_packet_pool_low_watermark;
+#endif /* NX_ENABLE_LOW_WATERMARK */
+} NX_PACKET_POOL;
+
+
+#ifndef NX_DISABLE_IPV4
+/* Define the Address Resolution Protocol (ARP) structure that makes up the
+   route table in each IP instance.  This is how IP addresses are translated
+   to physical addresses in the system.  */
+
+typedef struct NX_ARP_STRUCT
+{
+
+    /* Define a flag that indicates whether or not the mapping in this ARP
+       entry is static.  */
+    UINT nx_arp_route_static;
+
+    /* Define the counter that indicates when the next ARP update request is
+       sent.  This is always zero for static entries and initialized to the maximum
+       value for new entries.  */
+    UINT nx_arp_entry_next_update;
+
+    /* Define the ARP retry counter that is incremented each time the ARP request
+       is sent.  */
+    UINT nx_arp_retries;
+
+    /* Define the links for the IP ARP dynamic structures in the system.  This list
+       is maintained in a most recently used fashion.  */
+    struct NX_ARP_STRUCT
+        *nx_arp_pool_next,
+        *nx_arp_pool_previous;
+
+    /* Define the links for the active ARP entry that is part of route
+       information inside of an IP instance.  */
+    struct NX_ARP_STRUCT
+         *nx_arp_active_next,
+         *nx_arp_active_previous,
+        **nx_arp_active_list_head;
+
+    /* Define the IP address that this entry is setup for.  */
+    ULONG nx_arp_ip_address;
+
+    /* Define the physical address that maps to this IP address.  */
+    ULONG nx_arp_physical_address_msw;
+    ULONG nx_arp_physical_address_lsw;
+
+    /* Define the physical interface attached to this IP address. */
+    struct NX_INTERFACE_STRUCT *nx_arp_ip_interface;
+
+    /* Define a pointer to the queue holding one or more packets while address
+       resolution is pending. The maximum number of packets that can be queued
+       is defined by NX_APR_MAX_QUEUE_DEPTH. If ARP packet queue is exceeded,
+       the oldest packet is discarded in favor of keeping the newer packet.  */
+    struct NX_PACKET_STRUCT
+        *nx_arp_packets_waiting;
+} NX_ARP;
+#endif /* NX_DISABLE_IPV4 */
+
+
+/* Determine if the UDP control block has an extension defined. If not, 
+   define the extension to whitespace.  */
+
+#ifndef NX_UDP_SOCKET_MODULE_EXTENSION
+#define NX_UDP_SOCKET_MODULE_EXTENSION
+#endif
+
+
+/* Define the basic UDP socket structure.  This structure is used to manage all information
+   necessary to manage UDP transmission and reception.  */
+
+typedef struct NX_UDP_SOCKET_STRUCT
+{
+
+    /* Define the UDP identification that is used to determine if the UDP socket has
+       been created.  */
+    ULONG       nx_udp_socket_id;
+
+    /* Define the Application defined name for this UDP socket instance.  */
+    CHAR        *nx_udp_socket_name;
+
+    /* Define the UDP port that was bound to.  */
+    UINT        nx_udp_socket_port;
+
+    /* Define the entry that this UDP socket belongs to.  */
+    struct NX_IP_STRUCT
+                *nx_udp_socket_ip_ptr;
+
+    /* Define the statistic and error counters for this UDP socket.  */
+    ULONG       nx_udp_socket_packets_sent;
+    ULONG       nx_udp_socket_bytes_sent;
+    ULONG       nx_udp_socket_packets_received;
+    ULONG       nx_udp_socket_bytes_received;
+    ULONG       nx_udp_socket_invalid_packets;
+    ULONG       nx_udp_socket_packets_dropped;
+    ULONG       nx_udp_socket_checksum_errors;
+
+    /* Define the type of service for this UDP instance.  */
+    ULONG       nx_udp_socket_type_of_service;
+
+    /* Define the time-to-live for this UDP instance.  */
+    UINT        nx_udp_socket_time_to_live;
+
+    /* Define the fragment enable bit for this UDP instance.  */
+    ULONG       nx_udp_socket_fragment_enable;
+
+    /* Define the UDP checksum disable flag for this UDP socket.  */
+    UCHAR       nx_udp_socket_disable_checksum;
+
+#ifdef NX_ENABLE_VLAN
+    /* Defined the vlan priority for this UDP socket. */
+    UCHAR       nx_udp_socket_vlan_priority;
+
+    /* It is reserved for future use. */
+    UCHAR       nx_udp_socket_reserved[2];
+#else
+    /* It is reserved for future use. */
+    UCHAR       nx_udp_socket_reserved[3];
+#endif /* NX_ENABLE_VLAN */
+
+    /* Define the UDP receive packet queue pointers, queue counter, and
+       the maximum queue depth.  */
+    ULONG       nx_udp_socket_receive_count;
+    ULONG       nx_udp_socket_queue_maximum;
+    NX_PACKET   *nx_udp_socket_receive_head,
+                *nx_udp_socket_receive_tail;
+
+    /* Define the UDP socket bound list.  These pointers are used to manage the list
+       of UDP sockets on a particular hashed port index.  */
+    struct NX_UDP_SOCKET_STRUCT
+                *nx_udp_socket_bound_next,
+                *nx_udp_socket_bound_previous;
+
+    /* Define the UDP socket bind suspension thread pointer.  This pointer points
+       to the thread that that is suspended attempting to bind to a port that is
+       already bound to another socket.  */
+    TX_THREAD   *nx_udp_socket_bind_in_progress;
+
+    /* Define the UDP receive suspension list head associated with a count of
+       how many threads are suspended attempting to receive from the same UDP port.  */
+    TX_THREAD   *nx_udp_socket_receive_suspension_list;
+    ULONG       nx_udp_socket_receive_suspended_count;
+
+    /* Define the UDP bind suspension list head associated with a count of
+       how many threads are suspended attempting to bind to the same UDP port.  The
+       currently bound socket will maintain the head pointer.  When a socket unbinds,
+       the head of the suspension list is given the port and the remaining entries
+       of the suspension list are transferred to its suspension list head pointer.  */
+    TX_THREAD   *nx_udp_socket_bind_suspension_list;
+    ULONG       nx_udp_socket_bind_suspended_count;
+
+    /* Define the link between other UDP structures created by the application.  This
+       is linked to the IP instance the socket was created on.  */
+    struct NX_UDP_SOCKET_STRUCT
+                *nx_udp_socket_created_next,
+                *nx_udp_socket_created_previous;
+
+    /* Define the callback function for receive packet notification. If specified
+       by the application, this function is called whenever a receive packet is
+       available on for the socket.  */
+    VOID (*nx_udp_receive_callback)(struct NX_UDP_SOCKET_STRUCT *socket_ptr);
+
+    /* This pointer is reserved for application specific use.  */
+    /*lint -esym(768,NX_UDP_SOCKET_STRUCT::nx_udp_socket_reserved_ptr) suppress member not referenced. It is reserved for future use. */
+    void        *nx_udp_socket_reserved_ptr;
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+    /* Store a pointer to TCP/IP offload context.  */
+    VOID        *nx_udp_socket_tcpip_offload_context;
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+    /* Define the port extension in the UDP socket control block. This 
+       is typically defined to whitespace in nx_port.h.  */
+    NX_UDP_SOCKET_MODULE_EXTENSION
+    
+} NX_UDP_SOCKET;
+
+
+/* Determine if the TCP control block has an extension defined. If not, 
+   define the extension to whitespace.  */
+
+#ifndef NX_TCP_SOCKET_MODULE_EXTENSION
+#define NX_TCP_SOCKET_MODULE_EXTENSION
+#endif
+
+
+/* Define the basic TCP socket structure.  This structure is used to manage all information
+   necessary to manage TCP transmission and reception.  */
+
+typedef struct NX_TCP_SOCKET_STRUCT
+{
+
+    /* Define the TCP identification that is used to determine if the TCP socket has
+       been created.  */
+    ULONG       nx_tcp_socket_id;
+
+    /* Define the Application defined name for this TCP socket instance.  */
+    CHAR        *nx_tcp_socket_name;
+
+    /* Define the socket type flag.  If true, this socket is a client socket.  */
+    UINT        nx_tcp_socket_client_type;
+
+    /* Define the TCP port that was bound to.  */
+    UINT        nx_tcp_socket_port;
+
+    /* Define the TCP socket's maximum segment size (mss). By default, this is setup to the
+       IP's MTU less the size of the IP and TCP headers.  */
+    ULONG       nx_tcp_socket_mss;
+
+    /* Define the connected IP and port information.  */
+    NXD_ADDRESS nx_tcp_socket_connect_ip;
+    UINT        nx_tcp_socket_connect_port;
+    ULONG       nx_tcp_socket_connect_mss;
+    ULONG       nx_tcp_socket_peer_mss;
+    struct NX_INTERFACE_STRUCT
+                *nx_tcp_socket_connect_interface;
+    ULONG       nx_tcp_socket_next_hop_address;
+
+    /* mss2 is the holding place for the smss * smss value.
+       It is computed and stored here once for later use. */
+    ULONG       nx_tcp_socket_connect_mss2;
+
+    ULONG       nx_tcp_socket_tx_slow_start_threshold;
+
+    /* Define the state of the TCP connection.  */
+    UINT        nx_tcp_socket_state;
+
+    /* Define the receive and transmit sequence numbers.   */
+    ULONG       nx_tcp_socket_tx_sequence;
+    ULONG       nx_tcp_socket_rx_sequence;
+    ULONG       nx_tcp_socket_rx_sequence_acked;
+    ULONG       nx_tcp_socket_delayed_ack_timeout;
+    ULONG       nx_tcp_socket_fin_sequence;
+    USHORT      nx_tcp_socket_fin_received;
+    USHORT      nx_tcp_socket_fin_acked;
+
+    /* Track the advertised window size */
+    ULONG       nx_tcp_socket_tx_window_advertised;
+    ULONG       nx_tcp_socket_tx_window_congestion;
+    ULONG       nx_tcp_socket_tx_outstanding_bytes; /* Data transmitted but not acked. */
+
+    /* Define the transmit sequence that enters fast transmit. */
+    ULONG       nx_tcp_socket_tx_sequence_recover;
+
+    /* Define the previous cumulative acknowledgment.  */
+    ULONG       nx_tcp_socket_previous_highest_ack;
+
+    /* Counter for "ack-N-packet" */
+    ULONG       nx_tcp_socket_ack_n_packet_counter;
+
+    /* Counter for duplicated ACK  */
+    UINT        nx_tcp_socket_duplicated_ack_received;
+
+    /* Define the window size fields of the TCP socket structure.  */
+    ULONG       nx_tcp_socket_rx_window_default;
+    ULONG       nx_tcp_socket_rx_window_current;
+    ULONG       nx_tcp_socket_rx_window_last_sent;
+
+    /* Define the statistic and error counters for this TCP socket.  */
+    ULONG       nx_tcp_socket_packets_sent;
+    ULONG       nx_tcp_socket_bytes_sent;
+    ULONG       nx_tcp_socket_packets_received;
+    ULONG       nx_tcp_socket_bytes_received;
+    ULONG       nx_tcp_socket_retransmit_packets;
+    ULONG       nx_tcp_socket_checksum_errors;
+
+    /* Define data for zero window probe. */
+    ULONG       nx_tcp_socket_zero_window_probe_failure;
+    ULONG       nx_tcp_socket_zero_window_probe_sequence;
+    UCHAR       nx_tcp_socket_zero_window_probe_has_data;
+    UCHAR       nx_tcp_socket_zero_window_probe_data;
+
+    /* Define whether or not TCP socket is in fast recovery procedure. */
+    UCHAR       nx_tcp_socket_fast_recovery;
+
+#ifdef NX_ENABLE_HTTP_PROXY
+
+    /* Define the state of HTTP Proxy connection.  */
+    UCHAR       nx_tcp_socket_http_proxy_state;
+
+    /* Define the packet to store HTTP response header.  */
+    NX_PACKET   *nx_tcp_socket_http_proxy_header_packet;
+
+    /* Define the IP and port for original server.  */
+    NXD_ADDRESS nx_tcp_socket_original_server_ip;
+    UINT        nx_tcp_socket_original_server_port;
+#else
+    /* Reserved to four bytes alignment. */
+    /*lint -esym(768,NX_TCP_SOCKET_STRUCT::nx_tcp_socket_reserved) suppress member not referenced. It is reserved for future use. */
+    UCHAR       nx_tcp_socket_reserved;
+#endif /* NX_ENABLE_HTTP_PROXY  */
+
+    /* Define the entry that this TCP socket belongs to.  */
+    struct NX_IP_STRUCT
+                *nx_tcp_socket_ip_ptr;
+
+    /* Define the type of service for this TCP instance.  */
+    ULONG       nx_tcp_socket_type_of_service;
+
+    /* Define the time-to-live for this TCP instance.  */
+    UINT        nx_tcp_socket_time_to_live;
+
+    /* Define the fragment enable bit for this TCP instance.  */
+    ULONG       nx_tcp_socket_fragment_enable;
+
+    /* Define the TCP receive packet queue pointers, queue counter, and
+       the maximum queue depth.  */
+    ULONG       nx_tcp_socket_receive_queue_count;
+    NX_PACKET   *nx_tcp_socket_receive_queue_head,
+                *nx_tcp_socket_receive_queue_tail;
+
+    /* Define the TCP packet sent queue. This queue is used to keep track of the
+       transmit packets already send.  Before they can be released we need to receive
+       an ACK back from the other end of the connection.  If no ACK is received, the
+       packet(s) need to be re-transmitted.  */
+    ULONG       nx_tcp_socket_transmit_queue_maximum;
+    ULONG       nx_tcp_socket_transmit_sent_count;
+    NX_PACKET   *nx_tcp_socket_transmit_sent_head,
+                *nx_tcp_socket_transmit_sent_tail;
+
+    /* Define the maximum TCP packet receive queue. */
+#ifdef NX_ENABLE_LOW_WATERMARK
+    ULONG   nx_tcp_socket_receive_queue_maximum;
+#endif /* NX_ENABLE_LOW_WATERMARK */
+
+    /* Define the TCP transmit timeout parameters.  If the socket timeout is non-zero,
+       there is an active timeout on the TCP socket.  Subsequent timeouts are derived
+       from the timeout rate, which is adjusted higher as timeouts occur.  */
+    ULONG       nx_tcp_socket_timeout;
+    ULONG       nx_tcp_socket_timeout_rate;
+    ULONG       nx_tcp_socket_timeout_retries;
+    ULONG       nx_tcp_socket_timeout_max_retries;
+    UCHAR       nx_tcp_socket_timeout_shift;
+
+#ifdef NX_ENABLE_VLAN
+    /* Defined the vlan priority for this TCP socket. */
+    UCHAR       nx_tcp_socket_vlan_priority;
+
+    /*It is reserved for future use. */
+    UCHAR       nx_tcp_socket_reserved2[2];
+#else
+
+    /*It is reserved for future use. */
+    UCHAR       nx_tcp_socket_reserved2[3];
+#endif /* NX_ENABLE_VLAN */
+
+#ifdef NX_ENABLE_TCP_WINDOW_SCALING
+    /* Local receive window size, when user creates the TCP socket. */
+    ULONG       nx_tcp_socket_rx_window_maximum;
+
+    /* Window scale this side needs to offer to the peer. */
+    ULONG       nx_tcp_rcv_win_scale_value;
+
+    /* Window scale offered by the peer.  0xFF indicates the peer does not support window scaling. */
+    ULONG       nx_tcp_snd_win_scale_value;
+#endif /* NX_ENABLE_TCP_WINDOW_SCALING */
+
+    /* Define the TCP keepalive timer parameters.  If enabled with NX_ENABLE_TCP_KEEPALIVE,
+       these parameters are used to implement the keepalive timer.  */
+#ifdef NX_ENABLE_TCP_KEEPALIVE
+    ULONG       nx_tcp_socket_keepalive_timeout;
+    ULONG       nx_tcp_socket_keepalive_retries;
+#endif /* NX_ENABLE_TCP_KEEPALIVE */
+
+    /* Define the TCP socket bound list.  These pointers are used to manage the list
+       of TCP sockets on a particular hashed port index.  */
+    struct NX_TCP_SOCKET_STRUCT
+                *nx_tcp_socket_bound_next,
+                *nx_tcp_socket_bound_previous;
+
+    /* Define the TCP socket bind suspension thread pointer.  This pointer points
+       to the thread that that is suspended attempting to bind to a port that is
+       already bound to another socket.  */
+    TX_THREAD   *nx_tcp_socket_bind_in_progress;
+
+    /* Define the TCP receive suspension list head associated with a count of
+       how many threads are suspended attempting to receive from the same TCP port.  */
+    TX_THREAD   *nx_tcp_socket_receive_suspension_list;
+    ULONG       nx_tcp_socket_receive_suspended_count;
+
+    /* Define the TCP transmit suspension list head associated with a count of
+       how many threads are suspended attempting to transmit from the same TCP port.  */
+    TX_THREAD   *nx_tcp_socket_transmit_suspension_list;
+    ULONG       nx_tcp_socket_transmit_suspended_count;
+
+    /* Define the TCP connect suspension pointer that contains the pointer to the
+       thread suspended attempting to establish a TCP connection.  */
+    TX_THREAD   *nx_tcp_socket_connect_suspended_thread;
+
+    /* Define the TCP disconnect suspension pointer that contains the pointer to the
+       thread suspended attempting to break a TCP connection.  */
+    TX_THREAD   *nx_tcp_socket_disconnect_suspended_thread;
+
+    /* Define the TCP bind suspension list head associated with a count of
+       how many threads are suspended attempting to bind to the same TCP port.  The
+       currently bound socket will maintain the head pointer.  When a socket unbinds,
+       the head of the suspension list is given the port and the remaining entries
+       of the suspension list are transferred to its suspension list head pointer.  */
+    TX_THREAD   *nx_tcp_socket_bind_suspension_list;
+    ULONG       nx_tcp_socket_bind_suspended_count;
+
+    /* Define the link between other TCP structures created by the application.  This
+       is linked to the IP instance the socket was created on.  */
+    struct NX_TCP_SOCKET_STRUCT
+            *nx_tcp_socket_created_next,
+            *nx_tcp_socket_created_previous;
+
+    /* Define the callback function for urgent data reception.  This is for future use.  */
+    VOID (*nx_tcp_urgent_data_callback)(struct NX_TCP_SOCKET_STRUCT *socket_ptr);
+
+#ifndef NX_DISABLE_EXTENDED_NOTIFY_SUPPORT
+    /* Define the callback function for notifying an incoming SYN request. */
+    UINT (*nx_tcp_socket_syn_received_notify)(struct NX_TCP_SOCKET_STRUCT *socket_ptr, NX_PACKET *packet_ptr);
+
+    /* Define the callback function for notifying the host application of a connection handshake completion
+       with a remote host.  */
+    VOID (*nx_tcp_establish_notify)(struct NX_TCP_SOCKET_STRUCT *socket_ptr);
+
+    /* Define the callback function for notifying the host application of disconnection completion
+       with a remote host.  */
+    VOID (*nx_tcp_disconnect_complete_notify)(struct NX_TCP_SOCKET_STRUCT *socket_ptr);
+
+    /* Define the callback function for notifying the host application to set the socket
+       state in the timed wait state.  */
+    VOID (*nx_tcp_timed_wait_callback)(struct NX_TCP_SOCKET_STRUCT *socket_ptr);
+#endif
+
+    /* Define the callback function for disconnect detection from the other side of
+       the connection.  */
+    VOID (*nx_tcp_disconnect_callback)(struct NX_TCP_SOCKET_STRUCT *socket_ptr);
+
+    /* Define the callback function for receive packet notification. If specified
+       by the application, this function is called whenever a receive packet is
+       available on for the socket.  */
+    VOID (*nx_tcp_receive_callback)(struct NX_TCP_SOCKET_STRUCT *socket_ptr);
+
+    /* Define the callback function for receive packet notification. If specified
+       by the application, this function is called whenever a receive packet is
+       available on for the socket.  */
+    VOID (*nx_tcp_socket_window_update_notify)(struct NX_TCP_SOCKET_STRUCT *socket_ptr);
+
+#ifdef   NX_ENABLE_TCP_QUEUE_DEPTH_UPDATE_NOTIFY
+    VOID (*nx_tcp_socket_queue_depth_notify)(struct NX_TCP_SOCKET_STRUCT *socket_ptr);
+#endif
+
+    /* This pointer is reserved for application specific use.  */
+    /*lint -esym(768,NX_TCP_SOCKET_STRUCT::nx_tcp_socket_reserved_ptr) suppress member not referenced. It is reserved for application specific use. */
+    void    *nx_tcp_socket_reserved_ptr;
+
+    /* Define the default maximum queue size. This is necessary to dynamically
+       change the maximum queue size dynamically.  */
+    ULONG   nx_tcp_socket_transmit_queue_maximum_default;
+
+    /* Define a flag for enabling the keepalive feature per TCP socket. */
+#ifdef NX_ENABLE_TCP_KEEPALIVE
+    UINT    nx_tcp_socket_keepalive_enabled;
+#endif /* NX_ENABLE_TCP_KEEPALIVE */
+
+#ifdef FEATURE_NX_IPV6
+    struct NXD_IPV6_ADDRESS_STRUCT *nx_tcp_socket_ipv6_addr;
+#endif /* FEATURE_NX_IPV6 */
+
+#ifdef NX_IPSEC_ENABLE
+    /* Stores a pointer to the SA, if the traffic needs to be protected. */
+    VOID *nx_tcp_socket_egress_sa;
+
+    /* Number of bytes to offset from IP header.  This offset is needed to accommondate security header. */
+    UINT  nx_tcp_socket_egress_sa_data_offset;
+
+#endif /* NX_IPSEC_ENABLE */
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+    /* Store a pointer to TCP/IP offload context.  */
+    VOID *nx_tcp_socket_tcpip_offload_context;
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+    /* Define the port extension in the TCP socket control block. This 
+       is typically defined to whitespace in nx_port.h.  */
+    NX_TCP_SOCKET_MODULE_EXTENSION
+    
+} NX_TCP_SOCKET;
+
+
+/* Define the basic TCP listen request structure.  This structure is used to indicate
+   which, if any, TCP ports are allowing a client connection.  */
+
+typedef struct NX_TCP_LISTEN_STRUCT
+{
+
+    /* Define the port number that we are allowing a connection on.  */
+    UINT        nx_tcp_listen_port;
+
+    /* Define the listen callback routine that will be called when a connection
+       request is received.  */
+    VOID        (*nx_tcp_listen_callback)(NX_TCP_SOCKET *socket_ptr, UINT port);
+
+    /* Define the previously created socket for this listen request.  */
+    NX_TCP_SOCKET
+                *nx_tcp_listen_socket_ptr;
+
+    /* Define the listen queue for connect requests that come in when the previous socket
+       given for a listen or relisten has been used.  */
+    ULONG       nx_tcp_listen_queue_maximum;
+    ULONG       nx_tcp_listen_queue_current;
+    NX_PACKET   *nx_tcp_listen_queue_head,
+                *nx_tcp_listen_queue_tail;
+
+    /* Define the link between other TCP listen structures created by the application.  */
+    struct NX_TCP_LISTEN_STRUCT
+                *nx_tcp_listen_next,
+                *nx_tcp_listen_previous;
+} NX_TCP_LISTEN;
+
+/* There should be at least one physical interface. */
+#ifndef NX_MAX_PHYSICAL_INTERFACES
+#define NX_MAX_PHYSICAL_INTERFACES    1
+#endif /* NX_MAX_PHYSICAL_INTERFACES */
+
+#ifndef NX_MAX_IPV6_ADDRESSES
+#define NX_MAX_IPV6_ADDRESSES         (NX_MAX_PHYSICAL_INTERFACES * 3)
+#endif /* NX_MAX_IPV6_ADDRESSES */
+
+#if (NX_MAX_IPV6_ADDRESSES < 2)
+#error "NetX Duo needs at least 2 IPv6 interface addresses. "
+#endif
+
+#ifndef NX_DISABLE_LOOPBACK_INTERFACE
+/* Inside interface array, entries 0 up to NX_MAX_PHYSICAL_INTERFACES are assigned to the
+   physical interfaces.  Entry NX_MAX_PHYSICAL_INTERFACES is assigned to the loopback interface. */
+#define NX_LOOPBACK_INTERFACE         NX_MAX_PHYSICAL_INTERFACES
+#define NX_LOOPBACK_IPV6_SOURCE_INDEX NX_MAX_IPV6_ADDRESSES
+#define NX_LOOPBACK_IPV6_ENABLED      1
+#else
+#define NX_LOOPBACK_INTERFACE         0
+#define NX_LOOPBACK_IPV6_ENABLED      0
+#endif /* NX_DISALBE_LOOPBACK_INTERFACE */
+
+#if (defined(NX_DISABLE_LOOPBACK_INTERFACE) && (NX_MAX_PHYSICAL_INTERFACES == 0))
+#error "NetX is built without either physical interfaces or loopback interfaces."
+#endif
+
+#if defined(NX_DISABLE_LOOPBACK_INTERFACE)
+#define NX_MAX_IP_INTERFACES          NX_MAX_PHYSICAL_INTERFACES
+#else
+#define NX_MAX_IP_INTERFACES          (NX_MAX_PHYSICAL_INTERFACES + 1)
+#endif /* NX_DISABLE_LOOPBACK_INTERFACE */
+
+#ifdef NX_DISABLE_PACKET_CHAIN
+#ifndef NX_DISABLE_FRAGMENTATION
+#error "IP fragmentation is not supported if packet chain is disabled."
+#endif /* NX_DISABLE_FRAGMENTATION */
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+struct NX_IP_DRIVER_STRUCT;
+struct NX_LINK_TIME_STRUCT;
+struct NX_LINK_RECEIVE_QUEUE_STRUCT;
+struct NX_SHAPER_STRUCT;
+
+typedef struct NXD_IPV6_ADDRESS_STRUCT
+{
+    UCHAR nxd_ipv6_address_valid;
+
+    UCHAR nxd_ipv6_address_type;  /* IPv6 = 6 */
+
+    /* Current state:Invalid,Tentative...*/
+    UCHAR nxd_ipv6_address_state;
+
+    /* Prefix length */
+    UCHAR nxd_ipv6_address_prefix_length;
+
+    /* Pointer to the physical interface where this address is attached to.*/
+    struct NX_INTERFACE_STRUCT *nxd_ipv6_address_attached;
+
+    /* Interface address,in host byte order */
+    ULONG nxd_ipv6_address[4];
+
+    /* Pointer to the next address, or NX_NULL */
+    struct NXD_IPV6_ADDRESS_STRUCT *nxd_ipv6_address_next;
+
+    /* Number of DAD packets to be transmitted. */
+    /* This entry is used only if DAD is enabled. */
+    UCHAR nxd_ipv6_address_DupAddrDetectTransmit;
+
+    /* Describe how the interface is configured. */
+    UCHAR nxd_ipv6_address_ConfigurationMethod;
+
+    /* Define the index in array. */
+    UCHAR nxd_ipv6_address_index;
+
+    /* Reserved. */
+    /*lint -esym(768,NXD_IPV6_ADDRESS_STRUCT::reserved) suppress member not referenced. It is reserved for future use. */
+    UCHAR reserved;
+} NXD_IPV6_ADDRESS;
+
+/* Define the address interface structure. */
+typedef struct NX_INTERFACE_STRUCT
+{
+
+    /* Flag indicating whether or not the interface entry is valid. */
+    CHAR *nx_interface_name;
+    UCHAR nx_interface_valid;
+    UCHAR nx_interface_address_mapping_needed;
+
+    /* Define the Link Up field that is manipulated by the associated link driver.  */
+    UCHAR nx_interface_link_up;
+
+    /* Define the index in array. */
+    UCHAR nx_interface_index;
+
+    /* Define a flag to check if link status change. */
+    UCHAR nx_interface_link_status_change;
+
+#ifdef NX_ENABLE_VLAN
+    /* Define the VLAN tag control information.  */
+    UCHAR nx_interface_vlan_valid;
+    USHORT nx_interface_vlan_tag;
+#else
+    /*lint -esym(768,NX_INTERFACE_STRUCT::nx_interface_reserved) suppress member not referenced. It is reserved for future use. */
+    UCHAR nx_interface_reserved[3];
+#endif /* NX_ENABLE_VLAN */
+
+    /* Define the physical address of this IP instance.  These field are
+       setup by the link driver during initialization.  */
+    ULONG nx_interface_physical_address_msw;
+    ULONG nx_interface_physical_address_lsw;
+
+#ifndef NX_DISABLE_IPV4
+    /* Define the IP address of this IP instance.  Loopback can be done by
+       either using the same address or by using 127.*.*.*.  */
+    ULONG nx_interface_ip_address;
+
+    /* Define the network portion of the IP address.  */
+    ULONG nx_interface_ip_network_mask;
+
+    /* Define the network only bits of the IP address.  */
+    ULONG nx_interface_ip_network;
+#endif /* !NX_DISABLE_IPV4  */
+
+    /* Define the head of the interface IPv6 address list.
+       Typically the 1st entry on the list is the link local address,
+       followed by one or more global IPv6 addresses.
+     */
+    struct NXD_IPV6_ADDRESS_STRUCT *nxd_interface_ipv6_address_list_head;
+
+    /* Define information setup by the Link Driver.  */
+    ULONG nx_interface_ip_mtu_size;
+
+#ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
+
+    /* Maximum number of router solicitation messages to send. */
+    ULONG nx_ipv6_rtr_solicitation_max;
+
+    /* Number of router solicitation messages to be sent. */
+    ULONG nx_ipv6_rtr_solicitation_count;
+
+    /* Time (in seconds) before sending out another Router Solicitation message. */
+    ULONG nx_ipv6_rtr_solicitation_interval;
+
+    /* Count down timer for sending out  router solicitation message. */
+    ULONG nx_ipv6_rtr_solicitation_timer;
+#endif /* NX_DISABLE_ICMPV6_ROUTER_SOLICITATION */
+
+#ifdef NX_IPV6_STATELESS_AUTOCONFIG_CONTROL
+    ULONG nx_ipv6_stateless_address_autoconfig_status;
+#endif /* NX_IPV6_STATELESS_AUTOCONFIG_CONTROL    */
+    /* Define a pointer for use by the application.  Typically this is going to be
+       used by the link driver. */
+    VOID *nx_interface_additional_link_info;
+
+    /* Define the Link Driver entry point.  */
+    VOID        (*nx_interface_link_driver_entry)(struct NX_IP_DRIVER_STRUCT *);
+
+#ifdef NX_ENABLE_VLAN
+
+    /* Define the receive callback function queue.  */
+    struct NX_LINK_RECEIVE_QUEUE_STRUCT *nx_interface_link_receive_queue_head;
+
+    /* Define the parent interface.  */
+    struct NX_INTERFACE_STRUCT *nx_interface_parent_ptr;
+#endif /* NX_ENABLE_VLAN */
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    /* Define the capability flag of hardware for the interface. */
+    ULONG nx_interface_capability_flag;
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+#ifndef NX_DISABLE_IPV4
+    /* Define the ARP defend timeout.  */
+    ULONG nx_interface_arp_defend_timeout;
+
+    /* Define the IP probe address.  */
+    ULONG nx_interface_ip_probe_address;
+
+    /* Define the IP conflict notify handler. A non-null value for this function
+       pointer results in NetX calling it when an IP address is found in an incoming
+       ARP packet that matches that of nx_interface_ip_probe_address.  */
+    VOID        (*nx_interface_ip_conflict_notify_handler)(struct NX_IP_STRUCT *, UINT, ULONG, ULONG, ULONG);
+#endif /* !NX_DISABLE_IPV4  */
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+    /* Define the TCP/IP offload handler. */
+    UINT        (*nx_interface_tcpip_offload_handler)(struct NX_IP_STRUCT *ip_ptr,
+                                                      struct NX_INTERFACE_STRUCT *interface_ptr,
+                                                      VOID *socket_ptr, UINT operation, NX_PACKET *packet_ptr,
+                                                      NXD_ADDRESS *local_ip, NXD_ADDRESS *remote_ip,
+                                                      UINT local_port, UINT *remote_port, UINT wait_option);
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+#ifdef NX_ENABLE_VLAN
+    /* Define the shaper */
+    struct NX_SHAPER_CONTAINER_STRUCT *shaper_container;
+#endif /* NX_ENABLE_VLAN */
+} NX_INTERFACE;
+
+/* Define the static IPv4 routing table entry structure. */
+#if defined(NX_ENABLE_IP_STATIC_ROUTING) && !defined(NX_DISABLE_IPV4)
+typedef struct NX_IP_ROUTING_ENTRY_STRUCT
+{
+    /* Destination IP address, in host byte order */
+    ULONG nx_ip_routing_dest_ip;
+
+    /* Net mask, in host byte order */
+    ULONG nx_ip_routing_net_mask;
+
+    /* Next hop address, in host byte order.  */
+    ULONG nx_ip_routing_next_hop_address;
+
+    struct NX_INTERFACE_STRUCT
+        *nx_ip_routing_entry_ip_interface;
+} NX_IP_ROUTING_ENTRY;
+#endif /* defined(NX_ENABLE_IP_STATIC_ROUTING) && !defined(NX_DISABLE_IPV4) */
+
+#ifndef NX_DISABLE_IPV4
+typedef struct NX_IPV4_MULTICAST_STRUCT
+{
+
+    /* Define the multicast registered group list.  */
+    ULONG nx_ipv4_multicast_join_list;
+
+    /* Define the multicast regstiered group interface list. */
+    NX_INTERFACE *nx_ipv4_multicast_join_interface_list;
+
+    /* Define the multicast registration count.  */
+    ULONG nx_ipv4_multicast_join_count;
+
+    /* Define the multicast random time list.  */
+    ULONG nx_ipv4_multicast_update_time;
+
+    /* Define the multicast loopback flag list. This flag is set based on the global
+       loopback enable at the time the group was joined. */
+    UINT nx_ipv4_multicast_loopback_enable;
+} NX_IPV4_MULTICAST_ENTRY;
+#endif /* NX_DISABLE_IPV4 */
+
+#ifdef NX_ENABLE_IPV6_MULTICAST
+typedef struct NX_IPV6_MULTICAST_STRUCT
+{
+
+    /* Define the MLD registered group list.  */
+    ULONG nx_ip_mld_join_list[4];
+
+    /* Define the MLD regstiered group interface list. */
+    NX_INTERFACE *nx_ip_mld_join_interface_list;
+
+    /* Define the MLD registration count.  */
+    ULONG nx_ip_mld_join_count;
+} NX_IPV6_MULTICAST_ENTRY;
+
+#endif /* NX_ENABLE_IPV6_MULTICAST  */
+
+
+/* Determine if the IP control block has an extension defined. If not, 
+   define the extension to whitespace.  */
+
+#ifndef NX_IP_MODULE_EXTENSION
+#define NX_IP_MODULE_EXTENSION
+#endif
+
+
+/* Define the Internet Protocol (IP) structure.  Any number of IP instances
+   may be used by the application.  */
+
+typedef struct NX_IP_STRUCT
+{
+
+    /* Define the IP identification that is used to determine if the IP has
+       been created.  */
+    ULONG       nx_ip_id;
+
+    /* Define the Application defined name for this IP instance.  */
+    CHAR        *nx_ip_name;
+
+    /* Define the IP address of this IP instance.  Loopback can be done by
+       either using the same address or by using 127.*.*.*.  */
+#if 1
+#define nx_ip_address                  nx_ip_interface[0].nx_interface_ip_address
+#define nx_ip_driver_mtu               nx_ip_interface[0].nx_interface_ip_mtu_size
+#define nx_ip_driver_mapping_needed    nx_ip_interface[0].nx_interface_address_mapping_needed
+#define nx_ip_network_mask             nx_ip_interface[0].nx_interface_ip_network_mask
+#define nx_ip_network                  nx_ip_interface[0].nx_interface_ip_network
+#define nx_ip_arp_physical_address_msw nx_ip_interface[0].nx_interface_physical_address_msw
+#define nx_ip_arp_physical_address_lsw nx_ip_interface[0].nx_interface_physical_address_lsw
+#define nx_ip_driver_link_up           nx_ip_interface[0].nx_interface_link_up
+#define nx_ip_link_driver_entry        nx_ip_interface[0].nx_interface_link_driver_entry
+#define nx_ip_additional_link_info     nx_ip_interface[0].nx_interface_additional_link_info
+#endif
+
+#ifndef NX_DISABLE_IPV4
+    /* Define the gateway IP address.  */
+    ULONG       nx_ip_gateway_address;   /* In host byte order */
+
+    struct NX_INTERFACE_STRUCT
+               *nx_ip_gateway_interface;
+#endif /* !NX_DISABLE_IPV4  */
+
+#ifdef FEATURE_NX_IPV6
+    /* Define IPv6 addresses.  NetX6 allows user to specify Global address
+       in addition to the link-local address generated automatically. */
+    /* IPv6 address takes 16 bytes.  These addresses are 4-byte aligned */
+    struct NXD_IPV6_ADDRESS_STRUCT nx_ipv6_address[NX_MAX_IPV6_ADDRESSES + NX_LOOPBACK_IPV6_ENABLED];
+
+    /* Define the destination table. */
+    NX_IPV6_DESTINATION_ENTRY
+                nx_ipv6_destination_table[NX_IPV6_DESTINATION_TABLE_SIZE];
+
+    /* Define the ND cache table. */
+    ND_CACHE_ENTRY
+                nx_ipv6_nd_cache[NX_IPV6_NEIGHBOR_CACHE_SIZE];
+
+    /* Define the destination table size. */
+    UINT        nx_ipv6_destination_table_size;
+#endif /* FEATURE_NX_IPV6 */
+
+    /* Define the statistic and error counters for this IP instance.   */
+    ULONG       nx_ip_total_packet_send_requests;
+    ULONG       nx_ip_total_packets_sent;
+    ULONG       nx_ip_total_bytes_sent;
+    ULONG       nx_ip_total_packets_received;
+    ULONG       nx_ip_total_packets_delivered;
+    ULONG       nx_ip_total_bytes_received;
+    ULONG       nx_ip_packets_forwarded;
+    ULONG       nx_ip_packets_reassembled;
+    ULONG       nx_ip_reassembly_failures;
+    ULONG       nx_ip_invalid_packets;
+    ULONG       nx_ip_invalid_transmit_packets;
+    ULONG       nx_ip_invalid_receive_address;
+    ULONG       nx_ip_unknown_protocols_received;
+
+    /*lint -esym(768,NX_IP_STRUCT::nx_ip_transmit_no_route_errors) suppress member not referenced. It is reserved for application specific use. */
+    ULONG       nx_ip_transmit_resource_errors;
+    ULONG       nx_ip_transmit_no_route_errors;
+    ULONG       nx_ip_receive_packets_dropped;
+    ULONG       nx_ip_receive_checksum_errors;
+    ULONG       nx_ip_send_packets_dropped;
+    ULONG       nx_ip_total_fragment_requests;
+    ULONG       nx_ip_successful_fragment_requests;
+    ULONG       nx_ip_fragment_failures;
+    ULONG       nx_ip_total_fragments_sent;
+    ULONG       nx_ip_total_fragments_received;
+    ULONG       nx_ip_arp_requests_sent;
+    ULONG       nx_ip_arp_requests_received;
+    ULONG       nx_ip_arp_responses_sent;
+    ULONG       nx_ip_arp_responses_received;
+    ULONG       nx_ip_arp_aged_entries;
+    ULONG       nx_ip_arp_invalid_messages;
+    ULONG       nx_ip_arp_static_entries;
+    ULONG       nx_ip_udp_packets_sent;
+    ULONG       nx_ip_udp_bytes_sent;
+    ULONG       nx_ip_udp_packets_received;
+    ULONG       nx_ip_udp_bytes_received;
+    ULONG       nx_ip_udp_invalid_packets;
+    ULONG       nx_ip_udp_no_port_for_delivery;
+    ULONG       nx_ip_udp_receive_packets_dropped;
+    ULONG       nx_ip_udp_checksum_errors;
+    ULONG       nx_ip_tcp_packets_sent;
+    ULONG       nx_ip_tcp_bytes_sent;
+    ULONG       nx_ip_tcp_packets_received;
+    ULONG       nx_ip_tcp_bytes_received;
+    ULONG       nx_ip_tcp_invalid_packets;
+    ULONG       nx_ip_tcp_receive_packets_dropped;
+    ULONG       nx_ip_tcp_checksum_errors;
+    ULONG       nx_ip_tcp_connections;
+    ULONG       nx_ip_tcp_passive_connections;
+    ULONG       nx_ip_tcp_active_connections;
+    ULONG       nx_ip_tcp_disconnections;
+    ULONG       nx_ip_tcp_connections_dropped;
+    ULONG       nx_ip_tcp_retransmit_packets;
+    ULONG       nx_ip_tcp_resets_received;
+    ULONG       nx_ip_tcp_resets_sent;
+    ULONG       nx_ip_icmp_total_messages_received;
+    ULONG       nx_ip_icmp_checksum_errors;
+    ULONG       nx_ip_icmp_invalid_packets;
+    ULONG       nx_ip_icmp_unhandled_messages;
+    ULONG       nx_ip_pings_sent;
+    ULONG       nx_ip_ping_timeouts;
+    ULONG       nx_ip_ping_threads_suspended;
+    ULONG       nx_ip_ping_responses_received;
+    ULONG       nx_ip_pings_received;
+    ULONG       nx_ip_pings_responded_to;
+    ULONG       nx_ip_igmp_invalid_packets;
+    ULONG       nx_ip_igmp_reports_sent;
+    ULONG       nx_ip_igmp_queries_received;
+    ULONG       nx_ip_igmp_checksum_errors;
+    ULONG       nx_ip_igmp_groups_joined;
+#ifndef NX_DISABLE_IGMPV2
+    ULONG       nx_ip_igmp_router_version;
+#endif
+    ULONG       nx_ip_rarp_requests_sent;
+    ULONG       nx_ip_rarp_responses_received;
+    ULONG       nx_ip_rarp_invalid_messages;
+
+
+    /* Define the IP forwarding flag.  This is by default set to NX_NULL.
+       If forwarding is desired, the nx_ip_forward_packet_process service
+       pointed to by this member should be called.  */
+#ifndef NX_DISABLE_IPV4
+    VOID        (*nx_ip_forward_packet_process)(struct NX_IP_STRUCT *, NX_PACKET *);
+
+#ifdef NX_NAT_ENABLE
+    /*  Define the NAT forwarded packet handler. This is by default set to NX_NULL.  */
+    UINT        (*nx_ip_nat_packet_process)(struct NX_IP_STRUCT *, NX_PACKET *, UINT packet_process);
+
+    /*  Define the NAT port verify handler. This is by default set to NX_NULL.  */
+    UINT        (*nx_ip_nat_port_verify)(struct NX_IP_STRUCT *, UINT protocol, UINT port);
+#endif
+#endif /* !NX_DISABLE_IPV4  */
+
+#ifndef NX_ENABLE_IP_ID_RANDOMIZATION
+    /* Define the packet ID.  */
+    ULONG       nx_ip_packet_id;
+#endif /* NX_ENABLE_IP_ID_RANDOMIZATION */
+
+    /* Define the default packet pool.  */
+    struct NX_PACKET_POOL_STRUCT
+                *nx_ip_default_packet_pool;
+
+#ifdef NX_ENABLE_DUAL_PACKET_POOL
+    /* Define the auxiliary packet pool for internal usage. */
+    struct NX_PACKET_POOL_STRUCT
+                *nx_ip_auxiliary_packet_pool;
+#endif /* NX_ENABLE_DUAL_PACKET_POOL */
+
+    /* Define the internal mutex used for protection inside the NetX
+       data structures.  */
+    TX_MUTEX    nx_ip_protection;
+
+    /* Define the initialize done flag.  */
+    UINT        nx_ip_initialize_done;
+
+#ifdef NX_DRIVER_DEFERRED_PROCESSING
+    /* Define the Link Driver hardware deferred packet queue.  */
+    NX_PACKET   *nx_ip_driver_deferred_packet_head,
+                *nx_ip_driver_deferred_packet_tail;
+
+    /* Define the Link Driver hardware deferred packet processing routine.  If the driver
+       deferred processing is enabled, this routine is called from the IP helper thread.  */
+    VOID        (*nx_ip_driver_deferred_packet_handler)(struct NX_IP_STRUCT *, NX_PACKET *);
+#endif /* NX_DRIVER_DEFERRED_PROCESSING */
+
+    /* Define the deferred packet processing queue.  This is used to
+       process packets not initially processed in the receive ISR.  */
+    NX_PACKET   *nx_ip_deferred_received_packet_head,
+                *nx_ip_deferred_received_packet_tail;
+
+    /* Define the raw IP function pointer that also indicates whether or
+       not raw IP packet sending and receiving is enabled.  */
+    UINT        (*nx_ip_raw_ip_processing)(struct NX_IP_STRUCT *, ULONG, NX_PACKET *);
+
+#ifdef NX_ENABLE_IP_RAW_PACKET_FILTER
+    /* Define the raw packet filter function pointer. */
+    UINT        (*nx_ip_raw_packet_filter)(struct NX_IP_STRUCT *, ULONG, NX_PACKET *);
+#endif /* NX_ENABLE_IP_RAW_PACKET_FILTER */
+
+    /* Define the pointer to the raw IP packet queue.  */
+    NX_PACKET   *nx_ip_raw_received_packet_head,
+                *nx_ip_raw_received_packet_tail;
+
+    /* Define the count of raw IP packets on the queue.  */
+    ULONG       nx_ip_raw_received_packet_count;
+
+    /* Define the maximum number of packets queued for receive. */
+    ULONG       nx_ip_raw_received_packet_max;
+
+    /* Define the raw packet suspension list head along with a count of
+       how many threads are suspended.  */
+    TX_THREAD   *nx_ip_raw_packet_suspension_list;
+    ULONG       nx_ip_raw_packet_suspended_count;
+
+    /* Define the IP helper thread that processes periodic ARP requests,
+       reassembles IP messages, and helps handle TCP/IP packets.  */
+    TX_THREAD   nx_ip_thread;
+
+    /* Define the IP event flags that are used to stimulate the IP helper
+       thread.  */
+    TX_EVENT_FLAGS_GROUP
+                nx_ip_events;
+
+    /* Define the IP periodic timer for this IP instance.  */
+    TX_TIMER    nx_ip_periodic_timer;
+
+    /* Define the IP fragment function pointer that also indicates whether or
+       IP fragmenting is enabled.  */
+    VOID        (*nx_ip_fragment_processing)(struct NX_IP_DRIVER_STRUCT *);
+
+    /* Define the IP unfragment function pointer.  */
+    VOID        (*nx_ip_fragment_assembly)(struct NX_IP_STRUCT *);
+
+    /* Define the IP unfragment timeout checking function pointer.  */
+    VOID        (*nx_ip_fragment_timeout_check)(struct NX_IP_STRUCT *);
+
+    /* Define the fragment pointer to the oldest fragment re-assembly.  If this is
+       the same between any periodic the fragment re-assembly is too old and
+       will be deleted.  */
+    NX_PACKET   *nx_ip_timeout_fragment;
+
+    /* Define the pointer to the fragmented IP packet queue.  This queue is
+       appended when a fragmented packet is received and is drained inside
+       the IP.  */
+    NX_PACKET   *nx_ip_received_fragment_head,
+                *nx_ip_received_fragment_tail;
+
+    /* Define the pointer to the fragment re-assembly queue.  */
+    NX_PACKET   *nx_ip_fragment_assembly_head,
+                *nx_ip_fragment_assembly_tail;
+
+#ifdef NX_ENABLE_6LOWPAN
+    /* Define the created 6LoWPAN list. */
+    VOID        *nx_ip_6lowpan_created_ptr;
+
+#ifdef NX_ENABLE_THREAD
+    /* Define the created Thread list. */
+    VOID        *nx_ip_thread_created_ptr;
+#endif /* NX_ENABLE_THREAD  */
+#endif /* NX_ENABLE_6LOWPAN  */
+
+#ifndef NX_DISABLE_IPV4
+    /* Define the IP address change notification callback routine pointer.  */
+    VOID        (*nx_ip_address_change_notify)(struct NX_IP_STRUCT *, VOID *);
+    VOID        *nx_ip_address_change_notify_additional_info;
+
+    /* Define the internal IP address change notification callback routine pointer, used in mDNS.  */
+    VOID        (*nx_ip_address_change_notify_internal)(struct NX_IP_STRUCT *, VOID *);
+#endif /* !NX_DISABLE_IPV4  */
+
+#ifdef FEATURE_NX_IPV6
+#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
+    VOID        (*nx_ipv6_address_change_notify)(struct NX_IP_STRUCT *ip_ptr, UINT status, UINT interface_index, UINT addres_index, ULONG *ip_address);
+
+    /* Define the internal IPv6 address change notification callback routine pointer, used in mDNS.  */
+    VOID        (*nx_ipv6_address_change_notify_internal)(struct NX_IP_STRUCT *ip_ptr, UINT status, UINT interface_index, UINT addres_index, ULONG *ip_address);
+#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
+#endif /* FEATURE_NX_IPV6 */
+
+#ifndef NX_DISABLE_IPV4
+    /* Define the multicast entry. */
+    NX_IPV4_MULTICAST_ENTRY nx_ipv4_multicast_entry[NX_MAX_MULTICAST_GROUPS];
+
+    /* Define global IGMP loopback enable/disable flag. By default, IGMP loopback is
+       disabled.  */
+    UINT        nx_ip_igmp_global_loopback_enable;
+
+    /* Define the IGMP receive packet processing routine.  This is setup when IGMP
+       is enabled.  */
+    void        (*nx_ip_igmp_packet_receive)(struct NX_IP_STRUCT *, struct NX_PACKET_STRUCT *);
+
+    /* Define the IGMP periodic processing routine.  This is also setup when IGMP
+       is enabled.  */
+    void        (*nx_ip_igmp_periodic_processing)(struct NX_IP_STRUCT *);
+
+    /* Define the IGMP packet queue processing routine.  This is setup when IGMP is
+       enabled.  */
+    void        (*nx_ip_igmp_queue_process)(struct NX_IP_STRUCT *);
+
+    /* Define the IGMP message queue.  */
+    NX_PACKET   *nx_ip_igmp_queue_head;
+#endif /* !NX_DISABLE_IPV4  */
+
+    /* Define the ICMP sequence number.  This is used in ICMP messages that
+       require a sequence number.  */
+    ULONG       nx_ip_icmp_sequence;
+
+#ifdef NX_ENABLE_IPV6_MULTICAST
+
+    /* Define the IPv6 Multicast Group structure.  */
+    NX_IPV6_MULTICAST_ENTRY nx_ipv6_multicast_entry[NX_MAX_MULTICAST_GROUPS];
+
+    /* Define the MLD join count.  */
+    ULONG       nx_ipv6_multicast_groups_joined;
+
+#endif /* NX_ENABLE_IPV6_MULTICAST  */
+
+    /* Define the ICMP packet receive routine.  This also doubles as a
+       mechanism to make sure ICMP is enabled.  If this function is NULL, ICMP
+       is not enabled.  */
+    void        (*nx_ip_icmp_packet_receive)(struct NX_IP_STRUCT *, struct NX_PACKET_STRUCT *);
+
+#ifndef NX_DISABLE_IPV4
+    /* Define the ICMP packet queue processing routine.  This is setup when ICMP is
+       enabled.  */
+    void        (*nx_ip_icmp_queue_process)(struct NX_IP_STRUCT *);
+
+    /* Define the ICMP packet process routine */
+    void        (*nx_ip_icmpv4_packet_process)(struct NX_IP_STRUCT *, NX_PACKET *);
+#endif /* !NX_DISABLE_IPV4  */
+
+#ifdef FEATURE_NX_IPV6
+    /* Define the ICMPv6 packet process routine. */
+    void        (*nx_ip_icmpv6_packet_process)(struct NX_IP_STRUCT *, NX_PACKET *);
+
+    /* Define the Neighbor Discovery cache fast (10ms) periodic update routine. */
+    void        (*nx_nd_cache_fast_periodic_update)(struct NX_IP_STRUCT *);
+
+    /* Define the Neighbor Discovery cache slow (1000 ms) periodic update routine. */
+    void        (*nx_nd_cache_slow_periodic_update)(struct NX_IP_STRUCT *);
+
+    /* Define the ICMPv6 router advertisement flag callback. */
+    void        (*nx_icmpv6_ra_flag_callback)(struct NX_IP_STRUCT *, UINT);
+
+#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
+    /* Define the MTU path discovery periodic update. */
+    void        (*nx_destination_table_periodic_update)(struct NX_IP_STRUCT *);
+#endif
+
+#endif /* FEATURE_NX_IPV6 */
+
+
+    /* Define the ICMP message queue.  */
+    NX_PACKET   *nx_ip_icmp_queue_head;
+
+    /* Define the ICMP ping suspension list head associated with a count of
+       how many threads are suspended attempting to ping.  */
+    TX_THREAD   *nx_ip_icmp_ping_suspension_list;
+    ULONG        nx_ip_icmp_ping_suspended_count;
+
+    /* Define the UDP port information structure associated with this IP instance.  */
+    struct NX_UDP_SOCKET_STRUCT
+                *nx_ip_udp_port_table[NX_UDP_PORT_TABLE_SIZE];
+
+    /* Define the head pointer of the created UDP socket list.  */
+    struct NX_UDP_SOCKET_STRUCT
+                *nx_ip_udp_created_sockets_ptr;
+
+    /* Define the number of created UDP socket instances.  */
+    ULONG       nx_ip_udp_created_sockets_count;
+
+    /* Define the UDP packet receive routine.  This also doubles as a
+       mechanism to make sure UDP is enabled.  If this function is NULL, UDP
+       is not enabled.  */
+    void        (*nx_ip_udp_packet_receive)(struct NX_IP_STRUCT *, struct NX_PACKET_STRUCT *);
+
+    /* Define the TCP port information structure associated with this IP instance.  */
+    struct NX_TCP_SOCKET_STRUCT
+                *nx_ip_tcp_port_table[NX_TCP_PORT_TABLE_SIZE];
+
+    /* Define the head pointer of the created TCP socket list.  */
+    struct NX_TCP_SOCKET_STRUCT
+                *nx_ip_tcp_created_sockets_ptr;
+
+    /* Define the number of created TCP socket instances.  */
+    ULONG       nx_ip_tcp_created_sockets_count;
+
+    /* Define the TCP packet receive routine.  This also doubles as a
+       mechanism to make sure TCP is enabled.  If this function is NULL, TCP
+       is not enabled.  */
+    void        (*nx_ip_tcp_packet_receive)(struct NX_IP_STRUCT *, struct NX_PACKET_STRUCT *);
+
+    /* Define the TCP periodic processing routine for transmit timeout logic.  */
+    void        (*nx_ip_tcp_periodic_processing)(struct NX_IP_STRUCT *);
+
+    /* Define the TCP fast periodic processing routine for transmit timeout logic.  */
+    void        (*nx_ip_tcp_fast_periodic_processing)(struct NX_IP_STRUCT *);
+
+    /* Define the TCP packet queue processing routine.  This is setup when TCP is
+       enabled.  */
+    void        (*nx_ip_tcp_queue_process)(struct NX_IP_STRUCT *);
+
+    /* Define the pointer to the incoming TCP packet queue.  */
+    NX_PACKET   *nx_ip_tcp_queue_head,
+                *nx_ip_tcp_queue_tail;
+
+    /* Define the count of incoming TCP packets on the queue.  */
+    ULONG       nx_ip_tcp_received_packet_count;
+
+    /* Define the TCP listen request structure that contains the maximum number of
+       listen requests allowed for this IP instance.  */
+    NX_TCP_LISTEN
+                nx_ip_tcp_server_listen_reqs[NX_MAX_LISTEN_REQUESTS];
+
+    /* Define the head pointer of the available listen request structures.  */
+    NX_TCP_LISTEN
+                *nx_ip_tcp_available_listen_requests;
+
+    /* Define the head pointer of the active listen requests.  These are made
+       by issuing the nx_tcp_server_socket_listen service.  */
+    NX_TCP_LISTEN
+                *nx_ip_tcp_active_listen_requests;
+
+#ifdef NX_ENABLE_HTTP_PROXY
+    /* Define the IP address of HTTP proxy server.  */
+    NXD_ADDRESS nx_ip_http_proxy_ip_address;
+
+    /* Define the port of HTTP proxy server.  */
+    USHORT      nx_ip_http_proxy_port;
+
+    /* Define the flag indicating the HTTP proxy is enabled.  */
+    USHORT      nx_ip_http_proxy_enable;
+
+    /* Define the buffer for HTTP proxy authentication.  */
+    UCHAR       nx_ip_http_proxy_authentication[NX_HTTP_PROXY_MAX_AUTHENTICATION];
+    UINT        nx_ip_http_proxy_authentication_length;
+#endif /* NX_ENABLE_HTTP_PROXY */
+
+    /* Define a flag indicating the IP fast timer has been created */
+    UINT        nx_ip_fast_periodic_timer_created;
+
+    /* Define the fast IP periodic timer used for high resolution events for
+       this IP instance.  */
+    TX_TIMER    nx_ip_fast_periodic_timer;
+
+#ifndef NX_DISABLE_IPV4
+    /* Define the destination routing information associated with this IP
+       instance.  */
+    struct NX_ARP_STRUCT
+                *nx_ip_arp_table[NX_ARP_TABLE_SIZE];
+
+    /* Define the head pointer of the static ARP list.  */
+    struct NX_ARP_STRUCT
+                *nx_ip_arp_static_list;
+
+    /* Define the head pointer of the dynamic ARP list.  */
+    struct NX_ARP_STRUCT
+                *nx_ip_arp_dynamic_list;
+
+    /* Define the number of dynamic entries that are active.  */
+    ULONG       nx_ip_arp_dynamic_active_count;
+
+    /* Define the ARP deferred packet processing queue.  This is used to
+       process ARP packets not initially processed in the receive ISR.  */
+    NX_PACKET   *nx_ip_arp_deferred_received_packet_head,
+                *nx_ip_arp_deferred_received_packet_tail;
+
+    /* Define the ARP entry allocate routine.  This also doubles as a
+       mechanism to make sure ARP is enabled.  If this function is NULL, ARP
+       is not enabled.  */
+    UINT        (*nx_ip_arp_allocate)(struct NX_IP_STRUCT *, struct NX_ARP_STRUCT **, UINT);
+
+    /* Define the ARP periodic processing routine.  This is setup when ARP is
+       enabled.  */
+    void        (*nx_ip_arp_periodic_update)(struct NX_IP_STRUCT *);
+
+    /* Define the ARP receive queue processing routine.  This is setup when ARP is
+       enabled.  */
+    void        (*nx_ip_arp_queue_process)(struct NX_IP_STRUCT *);
+
+    /* Define the ARP send packet routine.  This is setup when ARP is
+       enabled.  */
+    void        (*nx_ip_arp_packet_send)(struct NX_IP_STRUCT *, ULONG destination_ip, NX_INTERFACE *nx_interface);
+
+    /* Define the ARP gratuitous response handler. This routine is setup in the
+       nx_arp_gratuitous_send function.  */
+    void        (*nx_ip_arp_gratuitous_response_handler)(struct NX_IP_STRUCT *, NX_PACKET *);
+
+#ifdef NX_ENABLE_ARP_MAC_CHANGE_NOTIFICATION
+    /* Define the ARP collision notify handler. A non-null value for this function
+       pointer results in NetX calling it whenever an IP address is found in an incoming
+       ARP packet that matches that of the IP address in our ARP table.  */
+    void        (*nx_ip_arp_collision_notify_response_handler)(void *);
+#endif
+
+    /* Define the ARP cache memory area.  This memory is supplied
+       by the ARP enable function and is carved up by that function into as
+       many ARP entries that will fit.  */
+    struct NX_ARP_STRUCT
+                *nx_ip_arp_cache_memory;
+
+    /* Define the number of ARP entries that will fit in the ARP cache.  */
+    ULONG       nx_ip_arp_total_entries;
+
+    /* Define the RARP periodic processing routine.  This is setup when RARP is
+       enabled.  It is also used to indicate RARP is enabled.  */
+    void        (*nx_ip_rarp_periodic_update)(struct NX_IP_STRUCT *);
+
+    /* Define the RARP receive queue processing routine.  This is setup when RARP is
+       enabled.  */
+    void        (*nx_ip_rarp_queue_process)(struct NX_IP_STRUCT *);
+
+    /* Define the RARP deferred packet processing queue.  This is used to
+       process RARP packets not initially processed in the receive ISR.  */
+    NX_PACKET   *nx_ip_rarp_deferred_received_packet_head,
+                *nx_ip_rarp_deferred_received_packet_tail;
+#endif /* !NX_DISABLE_IPV4  */
+
+    /* Define the link between other IP structures created by the application.  */
+    struct NX_IP_STRUCT
+                *nx_ip_created_next,
+                *nx_ip_created_previous;
+
+    /* This pointer is reserved for application specific use.  */
+    /*lint -esym(768,NX_IP_STRUCT::nx_ip_reserved_ptr) suppress member not referenced. */
+    void        *nx_ip_reserved_ptr;
+
+    /* Define the TCP devered cleanup processing routine.  */
+    void        (*nx_tcp_deferred_cleanup_check)(struct NX_IP_STRUCT *);
+
+    /* Define the interfaces attached to this IP instance. */
+    NX_INTERFACE nx_ip_interface[NX_MAX_IP_INTERFACES];
+
+#ifndef NX_DISABLE_IPV4
+    /* Define the IPv4 packet receive processing routine */
+    void        (*nx_ipv4_packet_receive)(struct NX_IP_STRUCT *, NX_PACKET *);
+
+    /* Define the static routing table, if the feature is enabled. */
+#ifdef NX_ENABLE_IP_STATIC_ROUTING
+
+    /* IPv4 static routing table. */
+    NX_IP_ROUTING_ENTRY
+                nx_ip_routing_table[NX_IP_ROUTING_TABLE_SIZE];
+
+    /* Number of entries in the IPv4 static routing table. */
+    ULONG       nx_ip_routing_table_entry_count;
+
+#endif /* NX_ENABLE_IP_STATIC_ROUTING */
+#endif /* !NX_DISABLE_IPV4  */
+
+#ifdef FEATURE_NX_IPV6
+
+    /* Number of valid entries in the IPv6 default router table. */
+    USHORT  nx_ipv6_default_router_table_size;
+
+    /* IPv6 default router table. */
+    NX_IPV6_DEFAULT_ROUTER_ENTRY nx_ipv6_default_router_table[NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE];
+
+    /* Create an index for round robin router selection. */
+    UINT  nx_ipv6_default_router_table_round_robin_index;
+
+    /*
+     * IPv6 prefix table. Entries in the prefix table are put into two lists:
+     *   the prefix list, and the free list. The prefix list keeps track of a list
+     *   of valid prefix entries.  The free list points to the unused entries.
+     */
+    NX_IPV6_PREFIX_ENTRY nx_ipv6_prefix_list_table[NX_IPV6_PREFIX_LIST_TABLE_SIZE];
+
+    /* Point to the 1st element of the prefix list. */
+    NX_IPV6_PREFIX_ENTRY *nx_ipv6_prefix_list_ptr;
+
+    /* Pointer to the 1st element of the prefix free list entry. */
+    NX_IPV6_PREFIX_ENTRY *nx_ipv6_prefix_entry_free_list;
+
+    /* Define the IPv6 packet receive processing routine */
+    void        (*nx_ipv6_packet_receive)(struct NX_IP_STRUCT *, NX_PACKET *);
+
+    /* Variable tracks the Neighbor Solicitation retransmission timer. */
+    ULONG       nx_ipv6_retrans_timer_ticks;
+
+    /* Variable tracks the Neighbor reachable timer. */
+    ULONG       nx_ipv6_reachable_timer;
+
+    /* Variable tracks the current hop_limit.  Hop limit is assigned by
+       routers through the router advertisement message. */
+    ULONG       nx_ipv6_hop_limit;
+
+#endif /* FEATURE_NX_IPV6 */
+
+#ifdef NX_IPSEC_ENABLE
+    /* Define the IPsec Authentication Header process function, for the received packet. */
+    UINT        (*nx_ip_ipsec_authentication_header_receive)(struct NX_IP_STRUCT *, NX_PACKET *, ULONG *, NX_PACKET **);
+
+    /* Define the IPsec Authentication Header process function, for the transmit packet. */
+    UINT        (*nx_ip_ipsec_authentication_header_transmit)(struct NX_IP_STRUCT *, NX_PACKET **, UINT, UINT);
+
+    /* Define the IPsec Encapsulating Security Payload header process function, for the received packet. */
+    UINT        (*nx_ip_ipsec_encapsulating_security_payload_receive)(struct NX_IP_STRUCT *, NX_PACKET *, ULONG *, NX_PACKET **);
+
+    /* Define the IPsec Encapsulating Security Payload header insert function, for the transmit packet. */
+    UINT        (*nx_ip_ipsec_encapsulating_security_payload_transmit)(struct NX_IP_STRUCT *, NX_PACKET **, UINT);
+
+    /* Define the IPsec egress SA lookup routine. This is called by TCP/UDP/ICMP/RAW packet send. */
+    UINT        (*nx_ip_packet_egress_sa_lookup)(struct NX_IP_STRUCT *ip_ptr,  NXD_ADDRESS *src_address,
+                                              NXD_ADDRESS *dst_address, UCHAR protocol, ULONG src_port, ULONG dest_port,
+                                              ULONG *data_offset, VOID **sa_ptr, UINT option);
+
+    /* Define the head pointer of the ingress SA list. */
+    VOID        *nx_ip_ipsec_ingress_sa_ptr;
+
+    /* Define the head pointer of the egress SA list. */
+    VOID        *nx_ip_ipsec_egress_sa_ptr;
+
+    /* Define the reference to IKEv2. */
+    VOID        *nx_ip_ipsec_ikev2_ptr;
+
+    /* Define the packet queue header in which packet is processed by hardware engine. */
+    NX_PACKET   *nx_ip_hw_done_packet_header_ptr;
+
+    /* Define the packet queue tail in which packet is processed by hardware engine. */
+    NX_PACKET   *nx_ip_hw_done_packet_tail_ptr;
+
+#endif /* NX_IPSEC_ENABLE */
+
+    /* Define the link status change notify routine. */
+    VOID        (*nx_ip_link_status_change_callback)(struct NX_IP_STRUCT *, UINT, UINT);
+
+#ifdef NX_ENABLE_IP_PACKET_FILTER
+    /* Define the IP packet filter routine.  */
+    UINT        (*nx_ip_packet_filter)(VOID *, UINT);
+
+    /* Define the IP packet filter extended routine.  */
+    /* Note: Developers are encouraged to use nx_ip_packet_filter_extended since nx_ip_packet_filter will be deprecated.*/
+    UINT        (*nx_ip_packet_filter_extended)(struct NX_IP_STRUCT *ip_ptr, NX_PACKET *packet_ptr, UINT direction);
+#endif /* NX_ENABLE_IP_PACKET_FILTER */
+
+    /* Define the port extension in the IP control block. This 
+       is typically defined to whitespace in nx_port.h.  */
+    NX_IP_MODULE_EXTENSION
+    
+} NX_IP;
+
+
+/* Define the Driver interface structure that is typically allocated off of the
+   local stack and passed to the IP Link Driver.  */
+
+typedef struct NX_IP_DRIVER_STRUCT
+{
+
+    /* Define the driver command.  */
+    UINT        nx_ip_driver_command;
+
+    /* Define the driver return status.  */
+    UINT        nx_ip_driver_status;
+
+    /* Define the physical address that maps to the destination IP address.  */
+    ULONG       nx_ip_driver_physical_address_msw;
+    ULONG       nx_ip_driver_physical_address_lsw;
+
+#ifdef NX_ENABLE_6LOWPAN
+    /* Define the length of physical address. Used by 6LoWPAN driver.  */
+    USHORT      nx_ip_driver_physical_address_length;
+
+    /* Define the 6LoWPAN sub driver command, see nx_6lowpan.h. Used by 6LoWPAN driver.  */
+    USHORT      nx_ip_driver_sub_command;
+#endif /* NX_ENABLE_6LOWPAN */
+
+    /* Define the datagram packet (if any) for the driver to send.  */
+    NX_PACKET   *nx_ip_driver_packet;
+
+    /* Define the return pointer for raw driver command requests.  */
+    ULONG       *nx_ip_driver_return_ptr;
+
+    /* Define the IP pointer associated with the request.  */
+    struct NX_IP_STRUCT
+                *nx_ip_driver_ptr;
+
+    NX_INTERFACE *nx_ip_driver_interface;
+} NX_IP_DRIVER;
+
+
+/* Define the system API mappings based on the error checking
+   selected by the user.  Note: this section is only applicable to
+   application source code, hence the conditional that turns off this
+   stuff when the include file is processed by the ThreadX source. */
+
+#ifndef NX_SOURCE_CODE
+
+/* Map old APIs to new APIs. */
+#define nx_ip_raw_packet_interface_send                 nx_ip_raw_packet_source_send
+#define nx_udp_socket_interface_send                    nx_udp_socket_source_send
+#define nxd_icmp_interface_ping                         nxd_icmp_source_ping
+#define nxd_ip_raw_packet_interface_send                nxd_ip_raw_packet_source_send
+#define nxd_ipv6_global_address_set(i, a, p)            nxd_ipv6_address_set(i, 0, a, p, NX_NULL)
+#define nxd_ipv6_linklocal_address_set(i, a)            nxd_ipv6_address_set(i, 0, a, 10, NX_NULL)
+#define nxd_udp_socket_interface_send                   nxd_udp_socket_source_send
+
+
+/* Determine if error checking is desired.  If so, map API functions
+   to the appropriate error checking front-ends.  Otherwise, map API
+   functions to the core functions that actually perform the work.
+   Note: error checking is enabled by default.  */
+
+#ifdef NX_DISABLE_ERROR_CHECKING
+/* Services without error checking.  */
+/* APIs for ARP. */
+#define nx_arp_dynamic_entries_invalidate               _nx_arp_dynamic_entries_invalidate
+#define nx_arp_dynamic_entry_set                        _nx_arp_dynamic_entry_set
+#define nx_arp_enable                                   _nx_arp_enable
+#define nx_arp_entry_delete                             _nx_arp_entry_delete
+#define nx_arp_gratuitous_send                          _nx_arp_gratuitous_send
+#define nx_arp_hardware_address_find                    _nx_arp_hardware_address_find
+#define nx_arp_info_get                                 _nx_arp_info_get
+#define nx_arp_ip_address_find                          _nx_arp_ip_address_find
+#define nx_arp_static_entries_delete                    _nx_arp_static_entries_delete
+#define nx_arp_static_entry_create                      _nx_arp_static_entry_create
+#define nx_arp_static_entry_delete                      _nx_arp_static_entry_delete
+
+/* APIs for ICMP. */
+#define nx_icmp_enable                                  _nx_icmp_enable
+#define nx_icmp_info_get                                _nx_icmp_info_get
+#define nx_icmp_ping                                    _nx_icmp_ping
+#define nxd_icmp_enable                                 _nxd_icmp_enable
+#define nxd_icmp_ping                                   _nxd_icmp_ping
+#define nxd_icmp_source_ping                            _nxd_icmp_source_ping
+#define nxd_icmpv6_ra_flag_callback_set                 _nxd_icmpv6_ra_flag_callback_set
+
+/* APIs for IGMP. */
+#define nx_igmp_enable                                  _nx_igmp_enable
+#define nx_igmp_info_get                                _nx_igmp_info_get
+#define nx_igmp_loopback_disable                        _nx_igmp_loopback_disable
+#define nx_igmp_multicast_leave                         _nx_igmp_multicast_leave
+#define nx_igmp_multicast_interface_join                _nx_igmp_multicast_interface_join
+#define nx_igmp_multicast_interface_leave               _nx_igmp_multicast_interface_leave
+#define nx_igmp_loopback_enable                         _nx_igmp_loopback_enable
+#define nx_igmp_multicast_join                          _nx_igmp_multicast_join
+
+/* APIs for IP. */
+#define nx_ip_address_change_notify                     _nx_ip_address_change_notify
+#define nx_ip_address_get                               _nx_ip_address_get
+#define nx_ip_address_set                               _nx_ip_address_set
+#define nx_ip_auxiliary_packet_pool_set                 _nx_ip_auxiliary_packet_pool_set
+#define nx_ip_create                                    _nx_ip_create
+#define nx_ip_delete                                    _nx_ip_delete
+#define nx_ip_driver_direct_command                     _nx_ip_driver_direct_command
+#define nx_ip_driver_interface_direct_command           _nx_ip_driver_interface_direct_command
+#define nx_ip_forwarding_disable                        _nx_ip_forwarding_disable
+#define nx_ip_forwarding_enable                         _nx_ip_forwarding_enable
+#define nx_ip_fragment_disable                          _nx_ip_fragment_disable
+#define nx_ip_fragment_enable                           _nx_ip_fragment_enable
+#define nx_ip_gateway_address_clear                     _nx_ip_gateway_address_clear
+#define nx_ip_gateway_address_get                       _nx_ip_gateway_address_get
+#define nx_ip_gateway_address_set                       _nx_ip_gateway_address_set
+#define nx_ip_info_get                                  _nx_ip_info_get
+#define nx_ip_interface_address_get                     _nx_ip_interface_address_get
+#define nx_ip_interface_address_mapping_configure       _nx_ip_interface_address_mapping_configure
+#define nx_ip_interface_address_set                     _nx_ip_interface_address_set
+#define nx_ip_interface_attach                          _nx_ip_interface_attach
+#define nx_ip_interface_capability_get                  _nx_ip_interface_capability_get
+#define nx_ip_interface_capability_set                  _nx_ip_interface_capability_set
+#define nx_ip_interface_detach                          _nx_ip_interface_detach
+#define nx_ip_interface_info_get                        _nx_ip_interface_info_get
+#define nx_ip_interface_mtu_set                         _nx_ip_interface_mtu_set
+#define nx_ip_interface_physical_address_get            _nx_ip_interface_physical_address_get
+#define nx_ip_interface_physical_address_set            _nx_ip_interface_physical_address_set
+#define nx_ip_interface_status_check                    _nx_ip_interface_status_check
+#define nx_ip_link_status_change_notify_set             _nx_ip_link_status_change_notify_set
+#define nx_ip_max_payload_size_find                     _nx_ip_max_payload_size_find
+#define nx_ip_status_check                              _nx_ip_status_check
+#define nx_ip_static_route_add                          _nx_ip_static_route_add
+#define nx_ip_static_route_delete                       _nx_ip_static_route_delete
+#define nx_ipv4_multicast_interface_join                _nx_ipv4_multicast_interface_join
+#define nx_ipv4_multicast_interface_leave               _nx_ipv4_multicast_interface_leave
+#define nxd_ipv6_address_change_notify                  _nxd_ipv6_address_change_notify
+#define nxd_ipv6_address_delete                         _nxd_ipv6_address_delete
+#define nxd_ipv6_address_get                            _nxd_ipv6_address_get
+#define nxd_ipv6_address_set                            _nxd_ipv6_address_set
+#define nxd_ipv6_default_router_add                     _nxd_ipv6_default_router_add
+#define nxd_ipv6_default_router_delete                  _nxd_ipv6_default_router_delete
+#define nxd_ipv6_default_router_entry_get               _nxd_ipv6_default_router_entry_get
+#define nxd_ipv6_default_router_get                     _nxd_ipv6_default_router_get
+#define nxd_ipv6_default_router_number_of_entries_get   _nxd_ipv6_default_router_number_of_entries_get
+#define nxd_ipv6_disable                                _nxd_ipv6_disable
+#define nxd_ipv6_enable                                 _nxd_ipv6_enable
+#define nxd_ipv6_multicast_interface_join               _nxd_ipv6_multicast_interface_join
+#define nxd_ipv6_multicast_interface_leave              _nxd_ipv6_multicast_interface_leave
+#define nxd_ipv6_stateless_address_autoconfig_disable   _nxd_ipv6_stateless_address_autoconfig_disable
+#define nxd_ipv6_stateless_address_autoconfig_enable    _nxd_ipv6_stateless_address_autoconfig_enable
+
+/* APIs for RAW service. */
+#define nx_ip_raw_packet_disable                        _nx_ip_raw_packet_disable
+#define nx_ip_raw_packet_enable                         _nx_ip_raw_packet_enable
+#define nx_ip_raw_packet_filter_set                     _nx_ip_raw_packet_filter_set
+#define nx_ip_raw_packet_receive                        _nx_ip_raw_packet_receive
+#define nx_ip_raw_packet_send                           _nx_ip_raw_packet_send
+#define nx_ip_raw_packet_source_send                    _nx_ip_raw_packet_source_send
+#define nx_ip_raw_receive_queue_max_set                 _nx_ip_raw_receive_queue_max_set
+#define nxd_ip_raw_packet_send                          _nxd_ip_raw_packet_send
+#define nxd_ip_raw_packet_source_send                   _nxd_ip_raw_packet_source_send
+
+/* APIs for ND cache. */
+#define nxd_nd_cache_entry_set                          _nxd_nd_cache_entry_set
+#define nxd_nd_cache_entry_delete                       _nxd_nd_cache_entry_delete
+#define nxd_nd_cache_hardware_address_find              _nxd_nd_cache_hardware_address_find
+#define nxd_nd_cache_invalidate                         _nxd_nd_cache_invalidate
+#define nxd_nd_cache_ip_address_find                    _nxd_nd_cache_ip_address_find
+
+/* APIs for packet pool. */
+#define nx_packet_allocate                              _nx_packet_allocate
+#define nx_packet_copy                                  _nx_packet_copy
+#define nx_packet_data_append                           _nx_packet_data_append
+#define nx_packet_data_extract_offset                   _nx_packet_data_extract_offset
+#define nx_packet_data_retrieve                         _nx_packet_data_retrieve
+#define nx_packet_length_get                            _nx_packet_length_get
+#define nx_packet_pool_create                           _nx_packet_pool_create
+#define nx_packet_pool_delete                           _nx_packet_pool_delete
+#define nx_packet_pool_info_get                         _nx_packet_pool_info_get
+#define nx_packet_pool_low_watermark_set                _nx_packet_pool_low_watermark_set
+#define nx_packet_release                               _nx_packet_release
+#define nx_packet_transmit_release                      _nx_packet_transmit_release
+#define nx_packet_vlan_priority_set                     _nx_packet_vlan_priority_set
+
+/* APIs for RARP. */
+#define nx_rarp_disable                                 _nx_rarp_disable
+#define nx_rarp_enable                                  _nx_rarp_enable
+#define nx_rarp_info_get                                _nx_rarp_info_get
+
+/* APIs for TCP. */
+#define nx_tcp_client_socket_bind                       _nx_tcp_client_socket_bind
+#define nx_tcp_client_socket_connect                    _nx_tcp_client_socket_connect
+#define nx_tcp_client_socket_port_get                   _nx_tcp_client_socket_port_get
+#define nx_tcp_client_socket_unbind                     _nx_tcp_client_socket_unbind
+#define nx_tcp_enable                                   _nx_tcp_enable
+#define nx_tcp_free_port_find                           _nx_tcp_free_port_find
+#define nx_tcp_info_get                                 _nx_tcp_info_get
+#define nx_tcp_server_socket_accept                     _nx_tcp_server_socket_accept
+#define nx_tcp_server_socket_listen                     _nx_tcp_server_socket_listen
+#define nx_tcp_server_socket_relisten                   _nx_tcp_server_socket_relisten
+#define nx_tcp_server_socket_unaccept                   _nx_tcp_server_socket_unaccept
+#define nx_tcp_server_socket_unlisten                   _nx_tcp_server_socket_unlisten
+#define nx_tcp_socket_bytes_available                   _nx_tcp_socket_bytes_available
+#define nx_tcp_socket_create                            _nx_tcp_socket_create
+#define nx_tcp_socket_delete                            _nx_tcp_socket_delete
+#define nx_tcp_socket_disconnect                        _nx_tcp_socket_disconnect
+#define nx_tcp_socket_disconnect_complete_notify        _nx_tcp_socket_disconnect_complete_notify
+#define nx_tcp_socket_establish_notify                  _nx_tcp_socket_establish_notify
+#define nx_tcp_socket_info_get                          _nx_tcp_socket_info_get
+#define nx_tcp_socket_mss_get                           _nx_tcp_socket_mss_get
+#define nx_tcp_socket_mss_peer_get                      _nx_tcp_socket_mss_peer_get
+#define nx_tcp_socket_mss_set                           _nx_tcp_socket_mss_set
+#define nx_tcp_socket_peer_info_get                     _nx_tcp_socket_peer_info_get
+#define nx_tcp_socket_queue_depth_notify_set            _nx_tcp_socket_queue_depth_notify_set
+#define nx_tcp_socket_receive                           _nx_tcp_socket_receive
+#define nx_tcp_socket_receive_notify                    _nx_tcp_socket_receive_notify
+#define nx_tcp_socket_receive_queue_max_set             _nx_tcp_socket_receive_queue_max_set
+#define nx_tcp_socket_send                              _nx_tcp_socket_send
+#define nx_tcp_socket_state_wait                        _nx_tcp_socket_state_wait
+#define nx_tcp_socket_timed_wait_callback               _nx_tcp_socket_timed_wait_callback
+#define nx_tcp_socket_transmit_configure                _nx_tcp_socket_transmit_configure
+#define nx_tcp_socket_window_update_notify_set          _nx_tcp_socket_window_update_notify_set
+#define nx_tcp_socket_vlan_priority_set                 _nx_tcp_socket_vlan_priority_set
+#define nxd_tcp_client_socket_connect                   _nxd_tcp_client_socket_connect
+#define nxd_tcp_socket_peer_info_get                    _nxd_tcp_socket_peer_info_get
+
+/* APIs for UDP. */
+
+#define nx_udp_enable                                   _nx_udp_enable
+#define nx_udp_free_port_find                           _nx_udp_free_port_find
+#define nx_udp_info_get                                 _nx_udp_info_get
+#define nx_udp_packet_info_extract                      _nx_udp_packet_info_extract
+#define nx_udp_socket_bind                              _nx_udp_socket_bind
+#define nx_udp_socket_bytes_available                   _nx_udp_socket_bytes_available
+#define nx_udp_socket_checksum_disable                  _nx_udp_socket_checksum_disable
+#define nx_udp_socket_checksum_enable                   _nx_udp_socket_checksum_enable
+#define nx_udp_socket_create                            _nx_udp_socket_create
+#define nx_udp_socket_delete                            _nx_udp_socket_delete
+#define nx_udp_socket_info_get                          _nx_udp_socket_info_get
+#define nx_udp_socket_port_get                          _nx_udp_socket_port_get
+#define nx_udp_socket_receive                           _nx_udp_socket_receive
+#define nx_udp_socket_receive_notify                    _nx_udp_socket_receive_notify
+#define nx_udp_socket_send                              _nx_udp_socket_send
+#define nx_udp_socket_source_send                       _nx_udp_socket_source_send
+#define nx_udp_socket_unbind                            _nx_udp_socket_unbind
+#define nx_udp_source_extract                           _nx_udp_source_extract
+#define nx_udp_socket_vlan_priority_set                 _nx_udp_socket_vlan_priority_set
+#define nxd_udp_packet_info_extract                     _nxd_udp_packet_info_extract
+#define nxd_udp_socket_send                             _nxd_udp_socket_send
+#define nxd_udp_socket_source_send                      _nxd_udp_socket_source_send
+#define nxd_udp_source_extract                          _nxd_udp_source_extract
+
+/* APIs for others. */
+#define nx_system_initialize                            _nx_system_initialize
+#define nx_http_proxy_client_enable                     _nx_http_proxy_client_enable
+
+#else
+
+/* Services with error checking.  */
+/* APIs for ARP. */
+#define nx_arp_dynamic_entries_invalidate               _nxe_arp_dynamic_entries_invalidate
+#define nx_arp_dynamic_entry_set                        _nxe_arp_dynamic_entry_set
+#define nx_arp_enable                                   _nxe_arp_enable
+#define nx_arp_entry_delete                             _nxe_arp_entry_delete
+#define nx_arp_gratuitous_send                          _nxe_arp_gratuitous_send
+#define nx_arp_hardware_address_find                    _nxe_arp_hardware_address_find
+#define nx_arp_info_get                                 _nxe_arp_info_get
+#define nx_arp_ip_address_find                          _nxe_arp_ip_address_find
+#define nx_arp_static_entries_delete                    _nxe_arp_static_entries_delete
+#define nx_arp_static_entry_create                      _nxe_arp_static_entry_create
+#define nx_arp_static_entry_delete                      _nxe_arp_static_entry_delete
+
+/* APIs for ICMP. */
+#define nx_icmp_enable                                  _nxe_icmp_enable
+#define nx_icmp_info_get                                _nxe_icmp_info_get
+#define nx_icmp_ping                                    _nxe_icmp_ping
+#define nxd_icmp_enable                                 _nxde_icmp_enable
+#define nxd_icmp_ping                                   _nxde_icmp_ping
+#define nxd_icmp_source_ping                            _nxde_icmp_source_ping
+#define nxd_icmpv6_ra_flag_callback_set                 _nxde_icmpv6_ra_flag_callback_set
+
+/* APIs for IGMP. */
+#define nx_igmp_enable                                  _nxe_igmp_enable
+#define nx_igmp_info_get                                _nxe_igmp_info_get
+#define nx_igmp_loopback_disable                        _nxe_igmp_loopback_disable
+#define nx_igmp_loopback_enable                         _nxe_igmp_loopback_enable
+#define nx_igmp_multicast_interface_join                _nxe_igmp_multicast_interface_join
+#define nx_igmp_multicast_interface_leave               _nxe_igmp_multicast_interface_leave
+#define nx_igmp_multicast_join                          _nxe_igmp_multicast_join
+#define nx_igmp_multicast_leave                         _nxe_igmp_multicast_leave
+
+/* APIs for IP. */
+#define nx_ip_address_change_notify                     _nxe_ip_address_change_notify
+#define nx_ip_address_get                               _nxe_ip_address_get
+#define nx_ip_address_set                               _nxe_ip_address_set
+#define nx_ip_auxiliary_packet_pool_set                 _nxe_ip_auxiliary_packet_pool_set
+#define nx_ip_create(i, n, a, m, d, l, p, s, y)         _nxe_ip_create(i, n, a, m, d, l, p, s, y, sizeof(NX_IP))
+#define nx_ip_delete                                    _nxe_ip_delete
+#define nx_ip_driver_direct_command                     _nxe_ip_driver_direct_command
+#define nx_ip_driver_interface_direct_command           _nxe_ip_driver_interface_direct_command
+#define nx_ip_forwarding_disable                        _nxe_ip_forwarding_disable
+#define nx_ip_forwarding_enable                         _nxe_ip_forwarding_enable
+#define nx_ip_fragment_disable                          _nxe_ip_fragment_disable
+#define nx_ip_fragment_enable                           _nxe_ip_fragment_enable
+#define nx_ip_gateway_address_clear                     _nxe_ip_gateway_address_clear
+#define nx_ip_gateway_address_get                       _nxe_ip_gateway_address_get
+#define nx_ip_gateway_address_set                       _nxe_ip_gateway_address_set
+#define nx_ip_info_get                                  _nxe_ip_info_get
+#define nx_ip_interface_address_get                     _nxe_ip_interface_address_get
+#define nx_ip_interface_address_mapping_configure       _nxe_ip_interface_address_mapping_configure
+#define nx_ip_interface_address_set                     _nxe_ip_interface_address_set
+#define nx_ip_interface_attach                          _nxe_ip_interface_attach
+#define nx_ip_interface_capability_get                  _nxe_ip_interface_capability_get
+#define nx_ip_interface_capability_set                  _nxe_ip_interface_capability_set
+#define nx_ip_interface_detach                          _nxe_ip_interface_detach
+#define nx_ip_interface_info_get                        _nxe_ip_interface_info_get
+#define nx_ip_interface_mtu_set                         _nxe_ip_interface_mtu_set
+#define nx_ip_interface_physical_address_get            _nxe_ip_interface_physical_address_get
+#define nx_ip_interface_physical_address_set            _nxe_ip_interface_physical_address_set
+#define nx_ip_interface_status_check                    _nxe_ip_interface_status_check
+#define nx_ip_link_status_change_notify_set             _nxe_ip_link_status_change_notify_set
+#define nx_ip_max_payload_size_find                     _nxe_ip_max_payload_size_find
+#define nx_ip_status_check                              _nxe_ip_status_check
+#define nx_ip_static_route_add                          _nxe_ip_static_route_add
+#define nx_ip_static_route_delete                       _nxe_ip_static_route_delete
+#define nx_ipv4_multicast_interface_join                _nxe_ipv4_multicast_interface_join
+#define nx_ipv4_multicast_interface_leave               _nxe_ipv4_multicast_interface_leave
+#define nxd_ipv6_address_change_notify                  _nxde_ipv6_address_change_notify
+#define nxd_ipv6_address_delete                         _nxde_ipv6_address_delete
+#define nxd_ipv6_address_get                            _nxde_ipv6_address_get
+#define nxd_ipv6_address_set                            _nxde_ipv6_address_set
+#define nxd_ipv6_default_router_add                     _nxde_ipv6_default_router_add
+#define nxd_ipv6_default_router_delete                  _nxde_ipv6_default_router_delete
+#define nxd_ipv6_default_router_entry_get               _nxde_ipv6_default_router_entry_get
+#define nxd_ipv6_default_router_get                     _nxde_ipv6_default_router_get
+#define nxd_ipv6_default_router_number_of_entries_get   _nxde_ipv6_default_router_number_of_entries_get
+#define nxd_ipv6_disable                                _nxde_ipv6_disable
+#define nxd_ipv6_enable                                 _nxde_ipv6_enable
+#define nxd_ipv6_multicast_interface_join               _nxde_ipv6_multicast_interface_join
+#define nxd_ipv6_multicast_interface_leave              _nxde_ipv6_multicast_interface_leave
+#define nxd_ipv6_stateless_address_autoconfig_disable   _nxde_ipv6_stateless_address_autoconfig_disable
+#define nxd_ipv6_stateless_address_autoconfig_enable    _nxde_ipv6_stateless_address_autoconfig_enable
+
+/* APIs for RAW service. */
+#define nx_ip_raw_packet_disable                        _nxe_ip_raw_packet_disable
+#define nx_ip_raw_packet_enable                         _nxe_ip_raw_packet_enable
+#define nx_ip_raw_packet_filter_set                     _nxe_ip_raw_packet_filter_set
+#define nx_ip_raw_packet_receive                        _nxe_ip_raw_packet_receive
+#define nx_ip_raw_packet_send(i, p, d, t)               _nxe_ip_raw_packet_send(i, &p, d, t)
+#define nx_ip_raw_packet_source_send(i, p, d, a, t)     _nxe_ip_raw_packet_source_send(i, &p, d, a, t)
+#define nx_ip_raw_receive_queue_max_set                 _nxe_ip_raw_receive_queue_max_set
+#define nxd_ip_raw_packet_send(i, p, d, t, l, s)        _nxde_ip_raw_packet_send(i, &p, d, t, l, s)
+#define nxd_ip_raw_packet_source_send                   _nxde_ip_raw_packet_source_send
+
+/* APIs for ND cache. */
+#define nxd_nd_cache_entry_set                          _nxde_nd_cache_entry_set
+#define nxd_nd_cache_entry_delete                       _nxde_nd_cache_entry_delete
+#define nxd_nd_cache_hardware_address_find              _nxde_nd_cache_hardware_address_find
+#define nxd_nd_cache_invalidate                         _nxde_nd_cache_invalidate
+#define nxd_nd_cache_ip_address_find                    _nxde_nd_cache_ip_address_find
+
+/* APIs for packet pool. */
+#define nx_packet_allocate                              _nxe_packet_allocate
+#define nx_packet_copy                                  _nxe_packet_copy
+#define nx_packet_data_append                           _nxe_packet_data_append
+#define nx_packet_data_extract_offset                   _nxe_packet_data_extract_offset
+#define nx_packet_data_retrieve                         _nxe_packet_data_retrieve
+#define nx_packet_length_get                            _nxe_packet_length_get
+#define nx_packet_pool_create(p, n, l, m, s)            _nxe_packet_pool_create(p, n, l, m, s, sizeof(NX_PACKET_POOL))
+#define nx_packet_pool_delete                           _nxe_packet_pool_delete
+#define nx_packet_pool_info_get                         _nxe_packet_pool_info_get
+#define nx_packet_pool_low_watermark_set                _nxe_packet_pool_low_watermark_set
+#define nx_packet_release(p)                            _nxe_packet_release(&p)
+#define nx_packet_transmit_release(p)                   _nxe_packet_transmit_release(&p)
+#define nx_packet_vlan_priority_set                     _nxe_packet_vlan_priority_set
+
+/* APIs for RARP. */
+#define nx_rarp_disable                                 _nxe_rarp_disable
+#define nx_rarp_enable                                  _nxe_rarp_enable
+#define nx_rarp_info_get                                _nxe_rarp_info_get
+
+/* APIs for TCP. */
+#define nx_tcp_client_socket_bind                       _nxe_tcp_client_socket_bind
+#define nx_tcp_client_socket_connect                    _nxe_tcp_client_socket_connect
+#define nx_tcp_client_socket_port_get                   _nxe_tcp_client_socket_port_get
+#define nx_tcp_client_socket_unbind                     _nxe_tcp_client_socket_unbind
+#define nx_tcp_enable                                   _nxe_tcp_enable
+#define nx_tcp_free_port_find                           _nxe_tcp_free_port_find
+#define nx_tcp_info_get                                 _nxe_tcp_info_get
+#define nx_tcp_server_socket_accept                     _nxe_tcp_server_socket_accept
+#define nx_tcp_server_socket_listen                     _nxe_tcp_server_socket_listen
+#define nx_tcp_server_socket_relisten                   _nxe_tcp_server_socket_relisten
+#define nx_tcp_server_socket_unaccept                   _nxe_tcp_server_socket_unaccept
+#define nx_tcp_server_socket_unlisten                   _nxe_tcp_server_socket_unlisten
+#define nx_tcp_socket_bytes_available                   _nxe_tcp_socket_bytes_available
+#define nx_tcp_socket_create(i, s, n, t, f, l, w, u, d) _nxe_tcp_socket_create(i, s, n, t, f, l, w, u, d, sizeof(NX_TCP_SOCKET))
+#define nx_tcp_socket_delete                            _nxe_tcp_socket_delete
+#define nx_tcp_socket_disconnect                        _nxe_tcp_socket_disconnect
+#define nx_tcp_socket_disconnect_complete_notify        _nxe_tcp_socket_disconnect_complete_notify
+#define nx_tcp_socket_establish_notify                  _nxe_tcp_socket_establish_notify
+#define nx_tcp_socket_info_get                          _nxe_tcp_socket_info_get
+#define nx_tcp_socket_mss_get                           _nxe_tcp_socket_mss_get
+#define nx_tcp_socket_mss_peer_get                      _nxe_tcp_socket_mss_peer_get
+#define nx_tcp_socket_mss_set                           _nxe_tcp_socket_mss_set
+#define nx_tcp_socket_peer_info_get                     _nxe_tcp_socket_peer_info_get
+#define nx_tcp_socket_queue_depth_notify_set            _nxe_tcp_socket_queue_depth_notify_set
+#define nx_tcp_socket_receive                           _nxe_tcp_socket_receive
+#define nx_tcp_socket_receive_notify                    _nxe_tcp_socket_receive_notify
+#define nx_tcp_socket_receive_queue_max_set             _nxe_tcp_socket_receive_queue_max_set
+#define nx_tcp_socket_send(s, p, t)                     _nxe_tcp_socket_send(s, &p, t)
+#define nx_tcp_socket_state_wait                        _nxe_tcp_socket_state_wait
+#define nx_tcp_socket_timed_wait_callback               _nxe_tcp_socket_timed_wait_callback
+#define nx_tcp_socket_transmit_configure                _nxe_tcp_socket_transmit_configure
+#define nx_tcp_socket_window_update_notify_set          _nxe_tcp_socket_window_update_notify_set
+#define nx_tcp_socket_vlan_priority_set                 _nxe_tcp_socket_vlan_priority_set
+#define nxd_tcp_client_socket_connect                   _nxde_tcp_client_socket_connect
+#define nxd_tcp_socket_peer_info_get                    _nxde_tcp_socket_peer_info_get
+
+/* APIs for UDP. */
+#define nx_udp_enable                                   _nxe_udp_enable
+#define nx_udp_free_port_find                           _nxe_udp_free_port_find
+#define nx_udp_info_get                                 _nxe_udp_info_get
+#define nx_udp_packet_info_extract                      _nxe_udp_packet_info_extract
+#define nx_udp_socket_bind                              _nxe_udp_socket_bind
+#define nx_udp_socket_bytes_available                   _nxe_udp_socket_bytes_available
+#define nx_udp_socket_checksum_disable                  _nxe_udp_socket_checksum_disable
+#define nx_udp_socket_checksum_enable                   _nxe_udp_socket_checksum_enable
+#define nx_udp_socket_create(i, s, n, t, f, l, q)       _nxe_udp_socket_create(i, s, n, t, f, l, q, sizeof(NX_UDP_SOCKET))
+#define nx_udp_socket_delete                            _nxe_udp_socket_delete
+#define nx_udp_socket_info_get                          _nxe_udp_socket_info_get
+#define nx_udp_socket_port_get                          _nxe_udp_socket_port_get
+#define nx_udp_socket_receive                           _nxe_udp_socket_receive
+#define nx_udp_socket_receive_notify                    _nxe_udp_socket_receive_notify
+#define nx_udp_socket_send(s, p, i, t)                  _nxe_udp_socket_send(s, &p, i, t)
+#define nx_udp_socket_source_send(s, p, i, t, a)        _nxe_udp_socket_source_send(s, &p, i, t, a)
+#define nx_udp_socket_unbind                            _nxe_udp_socket_unbind
+#define nx_udp_source_extract                           _nxe_udp_source_extract
+#define nx_udp_socket_vlan_priority_set                 _nxe_udp_socket_vlan_priority_set
+#define nxd_udp_packet_info_extract                     _nxde_udp_packet_info_extract
+#define nxd_udp_socket_send(s, p, i, t)                 _nxde_udp_socket_send(s, &p, i, t)
+#define nxd_udp_socket_source_send                      _nxde_udp_socket_source_send
+#define nxd_udp_source_extract                          _nxde_udp_source_extract
+
+/* APIs for others. */
+#define nx_system_initialize                            _nx_system_initialize
+#define nx_http_proxy_client_enable                     _nxe_http_proxy_client_enable
+#endif
+
+
+/* Define the function prototypes of the NetX Duo API.  */
+
+/* APIs for ARP. */
+UINT nx_arp_dynamic_entries_invalidate(NX_IP *ip_ptr);
+UINT nx_arp_dynamic_entry_set(NX_IP *ip_ptr, ULONG ip_address,  ULONG physical_msw, ULONG physical_lsw);
+UINT nx_arp_enable(NX_IP *ip_ptr, VOID *arp_cache_memory, ULONG arp_cache_size);
+UINT nx_arp_entry_delete(NX_IP *ip_ptr, ULONG ip_address);
+UINT nx_arp_gratuitous_send(NX_IP *ip_ptr, VOID (*response_handler)(NX_IP *ip_ptr, NX_PACKET *packet_ptr));
+UINT nx_arp_hardware_address_find(NX_IP *ip_ptr, ULONG ip_address, ULONG *physical_msw, ULONG *physical_lsw);
+UINT nx_arp_info_get(NX_IP *ip_ptr, ULONG *arp_requests_sent, ULONG *arp_requests_received,
+                     ULONG *arp_responses_sent, ULONG *arp_responses_received,
+                     ULONG *arp_dynamic_entries, ULONG *arp_static_entries,
+                     ULONG *arp_aged_entries, ULONG *arp_invalid_messages);
+UINT nx_arp_ip_address_find(NX_IP *ip_ptr, ULONG *ip_address,  ULONG physical_msw, ULONG physical_lsw);
+UINT nx_arp_static_entries_delete(NX_IP *ip_ptr);
+UINT nx_arp_static_entry_create(NX_IP *ip_ptr, ULONG ip_address, ULONG physical_msw, ULONG physical_lsw);
+UINT nx_arp_static_entry_delete(NX_IP *ip_ptr, ULONG ip_address,  ULONG physical_msw, ULONG physical_lsw);
+
+/* APIs for ICMP. */
+UINT nx_icmp_enable(NX_IP *ip_ptr);
+UINT nx_icmp_info_get(NX_IP *ip_ptr, ULONG *pings_sent, ULONG *ping_timeouts,
+                      ULONG *ping_threads_suspended, ULONG *ping_responses_received,
+                      ULONG *icmp_checksum_errors, ULONG *icmp_unhandled_messages);
+UINT nx_icmp_ping(NX_IP *ip_ptr, ULONG ip_address, CHAR *data, ULONG data_size,
+                  NX_PACKET **response_ptr, ULONG wait_option);
+UINT nxd_icmp_enable(NX_IP *ip_ptr);
+UINT nxd_icmp_ping(NX_IP *ip_ptr, NXD_ADDRESS *ip_address, CHAR *data_ptr, ULONG data_size,
+                   NX_PACKET **response_ptr, ULONG wait_option);
+UINT nxd_icmp_source_ping(NX_IP *ip_ptr, NXD_ADDRESS *ip_address, UINT address_index, CHAR *data_ptr,
+                          ULONG data_size, NX_PACKET **response_ptr, ULONG wait_option);
+UINT nxd_icmpv6_ra_flag_callback_set(NX_IP *ip_ptr,
+                                     VOID (*icmpv6_ra_flag_callback)(NX_IP *ip_ptr, UINT ra_flag));
+
+/* APIs for IGMP. */
+UINT nx_igmp_enable(NX_IP *ip_ptr);
+UINT nx_igmp_info_get(NX_IP *ip_ptr, ULONG *igmp_reports_sent, ULONG *igmp_queries_received,
+                      ULONG *igmp_checksum_errors, ULONG *current_groups_joined);
+UINT nx_igmp_loopback_disable(NX_IP *ip_ptr);
+UINT nx_igmp_loopback_enable(NX_IP *ip_ptr);
+UINT nx_igmp_multicast_interface_join(NX_IP *ip_ptr, ULONG group_address, UINT interface_index);
+UINT nx_igmp_multicast_interface_leave(NX_IP *ip_ptr, ULONG group_address, UINT interface_index);
+UINT nx_igmp_multicast_join(NX_IP *ip_ptr, ULONG group_address);
+UINT nx_igmp_multicast_leave(NX_IP *ip_ptr, ULONG group_address);
+
+/* APIs for IP. */
+UINT nx_ip_address_change_notify(NX_IP *ip_ptr, VOID (*ip_address_change_notify)(NX_IP *, VOID *), VOID *additional_info);
+UINT nx_ip_address_get(NX_IP *ip_ptr, ULONG *ip_address, ULONG *network_mask);
+UINT nx_ip_address_set(NX_IP *ip_ptr, ULONG ip_address, ULONG network_mask);
+UINT nx_ip_auxiliary_packet_pool_set(NX_IP *ip_ptr, NX_PACKET_POOL *auxiliary_pool);
+#ifndef NX_DISABLE_ERROR_CHECKING
+UINT _nxe_ip_create(NX_IP *ip_ptr, CHAR *name, ULONG ip_address, ULONG network_mask,
+                    NX_PACKET_POOL *default_pool,
+                    VOID (*ip_link_driver)(NX_IP_DRIVER *),
+                    VOID *memory_ptr, ULONG memory_size, UINT priority, UINT ip_control_block_size);
+#else
+UINT _nx_ip_create(NX_IP *ip_ptr, CHAR *name, ULONG ip_address, ULONG network_mask,
+                   NX_PACKET_POOL *default_pool,
+                   VOID (*ip_link_driver)(NX_IP_DRIVER *),
+                   VOID *memory_ptr, ULONG memory_size, UINT priority);
+#endif
+UINT nx_ip_delete(NX_IP *ip_ptr);
+UINT nx_ip_driver_direct_command(NX_IP *ip_ptr, UINT command, ULONG *return_value_ptr);
+UINT nx_ip_driver_interface_direct_command(NX_IP *ip_ptr, UINT command, UINT interface_index, ULONG *return_value_ptr);
+UINT nx_ip_forwarding_disable(NX_IP *ip_ptr);
+UINT nx_ip_forwarding_enable(NX_IP *ip_ptr);
+UINT nx_ip_fragment_disable(NX_IP *ip_ptr);
+UINT nx_ip_fragment_enable(NX_IP *ip_ptr);
+UINT nx_ip_gateway_address_clear(NX_IP *ip_ptr);
+UINT nx_ip_gateway_address_get(NX_IP *ip_ptr, ULONG *ip_address);
+UINT nx_ip_gateway_address_set(NX_IP *ip_ptr, ULONG ip_address);
+UINT nx_ip_info_get(NX_IP *ip_ptr, ULONG *ip_total_packets_sent, ULONG *ip_total_bytes_sent,
+                    ULONG *ip_total_packets_received, ULONG *ip_total_bytes_received,
+                    ULONG *ip_invalid_packets, ULONG *ip_receive_packets_dropped,
+                    ULONG *ip_receive_checksum_errors, ULONG *ip_send_packets_dropped,
+                    ULONG *ip_total_fragments_sent, ULONG *ip_total_fragments_received);
+UINT nx_ip_interface_address_get(NX_IP *ip_ptr, UINT interface_index, ULONG *ip_address, ULONG *network_mask);
+UINT nx_ip_interface_address_mapping_configure(NX_IP *ip_ptr, UINT interface_index, UINT mapping_needed);
+UINT nx_ip_interface_address_set(NX_IP *ip_ptr, UINT interface_index, ULONG ip_address, ULONG network_mask);
+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 *));
+UINT nx_ip_interface_capability_get(NX_IP *ip_ptr, UINT interface_index, ULONG *interface_capability_flag);
+UINT nx_ip_interface_capability_set(NX_IP *ip_ptr, UINT interface_index, ULONG interface_capability_flag);
+UINT nx_ip_interface_detach(NX_IP *ip_ptr, UINT index);
+UINT nx_ip_interface_info_get(NX_IP *ip_ptr, UINT interface_index, CHAR **interface_name, ULONG *ip_address,
+                              ULONG *network_mask, ULONG *mtu_size, ULONG *physical_address_msw,
+                              ULONG *physical_address_lsw);
+UINT nx_ip_interface_mtu_set(NX_IP *ip_ptr, UINT interface_index, ULONG mtu_size);
+UINT nx_ip_interface_physical_address_get(NX_IP *ip_ptr, UINT interface_index, ULONG *physical_msw,
+                                          ULONG *physical_lsw);
+UINT nx_ip_interface_physical_address_set(NX_IP *ip_ptr, UINT interface_index, ULONG physical_msw,
+                                          ULONG physical_lsw, UINT update_driver);
+UINT nx_ip_interface_status_check(NX_IP *ip_ptr, UINT interface_index, ULONG needed_status,
+                                  ULONG *actual_status, ULONG wait_option);
+UINT nx_ip_link_status_change_notify_set(NX_IP *ip_ptr,
+                                         VOID (*link_status_change_notify)(NX_IP *ip_ptr,
+                                                                           UINT interface_index,
+                                                                           UINT link_up));
+UINT nx_ip_max_payload_size_find(NX_IP *ip_ptr, NXD_ADDRESS *dest_address, UINT if_index,
+                                 UINT src_port, UINT dest_port, ULONG protocol, ULONG *start_offset_ptr,
+                                 ULONG *payload_length_ptr);
+UINT nx_ip_status_check(NX_IP *ip_ptr, ULONG needed_status, ULONG *actual_status, ULONG wait_option);
+UINT nx_ip_static_route_add(NX_IP *ip_ptr, ULONG network_address, ULONG net_mask, ULONG next_hop);
+UINT nx_ip_static_route_delete(NX_IP *ip_ptr, ULONG network_address, ULONG net_mask);
+UINT nx_ipv4_multicast_interface_join(NX_IP *ip_ptr, ULONG group_address, UINT interface_index);
+UINT nx_ipv4_multicast_interface_leave(NX_IP *ip_ptr, ULONG group_address, UINT interface_index);
+UINT nxd_ipv6_address_change_notify(NX_IP *ip_ptr,
+                                    VOID (*ip_address_change_notify)(NX_IP *ip_ptr, UINT status, UINT interface_index, UINT address_index, ULONG *ip_address));
+UINT nxd_ipv6_address_delete(NX_IP *ip_ptr, UINT address_index);
+UINT nxd_ipv6_address_get(NX_IP *ip_ptr, UINT address_index, NXD_ADDRESS *ip_address,
+                          ULONG *prefix_length, UINT *interface_index);
+UINT nxd_ipv6_address_set(NX_IP *ip_ptr, UINT interface_index, NXD_ADDRESS *ip_address,
+                          ULONG prefix_length, UINT *address_index);
+UINT nxd_ipv6_default_router_add(NX_IP *ip_ptr, NXD_ADDRESS *router_addr,
+                                 ULONG router_lifetime, UINT interface_index);
+UINT nxd_ipv6_default_router_delete(NX_IP *ip_ptr, NXD_ADDRESS *router_addr);
+UINT nxd_ipv6_default_router_entry_get(NX_IP *ip_ptr, UINT interface_index, UINT entry_index,
+                                       NXD_ADDRESS *router_addr, ULONG *router_lifetime,
+                                       ULONG *prefix_length, ULONG *configuration_method);
+UINT nxd_ipv6_default_router_get(NX_IP *ip_ptr, UINT interface_index, NXD_ADDRESS *router_addr,
+                                 ULONG *router_lifetime, ULONG *prefix_length);
+UINT nxd_ipv6_default_router_number_of_entries_get(NX_IP *ip_ptr, UINT interface_index, UINT *num_entries);
+UINT nxd_ipv6_disable(NX_IP *ip_ptr);
+UINT nxd_ipv6_enable(NX_IP *ip_ptr);
+UINT nxd_ipv6_multicast_interface_join(NX_IP *ip_ptr, NXD_ADDRESS *group_address, UINT interface_index);
+UINT nxd_ipv6_multicast_interface_leave(NX_IP *ip_ptr, NXD_ADDRESS *group_address, UINT interface_index);
+UINT nxd_ipv6_stateless_address_autoconfig_disable(NX_IP *ip_ptr, UINT interface_index);
+UINT nxd_ipv6_stateless_address_autoconfig_enable(NX_IP *ip_ptr, UINT interface_index);
+
+/* APIs for RAW service. */
+UINT nx_ip_raw_packet_disable(NX_IP *ip_ptr);
+UINT nx_ip_raw_packet_enable(NX_IP *ip_ptr);
+UINT nx_ip_raw_packet_filter_set(NX_IP *ip_ptr, UINT (*raw_packet_filter)(NX_IP *, ULONG, NX_PACKET *));
+UINT nx_ip_raw_packet_receive(NX_IP *ip_ptr, NX_PACKET **packet_ptr, ULONG wait_option);
+#ifndef NX_DISABLE_ERROR_CHECKING
+UINT _nxe_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET **packet_ptr_ptr,
+                             ULONG destination_ip, ULONG type_of_service);
+UINT _nxe_ip_raw_packet_source_send(NX_IP *ip_ptr, NX_PACKET **packet_ptr_ptr,
+                                    ULONG destination_ip, UINT address_index, ULONG type_of_service);
+#else
+UINT _nx_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,
+                            ULONG destination_ip, ULONG type_of_service);
+UINT _nx_ip_raw_packet_source_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,
+                                   ULONG destination_ip, UINT address_index, ULONG type_of_service);
+#endif /* NX_DISABLE_ERROR_CHECKING */
+UINT nx_ip_raw_receive_queue_max_set(NX_IP *ip_ptr, ULONG queue_max);
+#ifndef NX_DISABLE_ERROR_CHECKING
+UINT _nxde_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET **packet_ptr_ptr, NXD_ADDRESS *destination_ip,
+                              ULONG protocol, UINT ttl, ULONG tos);
+#else /* NX_DISABLE_ERROR_CHECKING */
+UINT _nxd_ip_raw_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,  NXD_ADDRESS *destination_ip,
+                             ULONG protocol, UINT ttl, ULONG tos);
+#endif /* NX_DISABLE_ERROR_CHECKING */
+UINT nxd_ip_raw_packet_source_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, NXD_ADDRESS *destination_ip,
+                                   UINT address_index, ULONG protocol, UINT ttl, ULONG tos);
+
+/* APIs for ND cache. */
+UINT nxd_nd_cache_entry_set(NX_IP *ip_ptr, ULONG *dest_ip, UINT interface_index, CHAR *mac);
+UINT nxd_nd_cache_entry_delete(NX_IP *ip_ptr, ULONG *dest_ip);
+UINT nxd_nd_cache_hardware_address_find(NX_IP *ip_ptr, NXD_ADDRESS *ip_address,
+                                        ULONG *physical_msw, ULONG *physical_lsw, UINT *interface_index);
+UINT nxd_nd_cache_invalidate(NX_IP *ip_ptr);
+UINT nxd_nd_cache_ip_address_find(NX_IP *ip_ptr, NXD_ADDRESS *ip_address,
+                                  ULONG physical_msw, ULONG physical_lsw, UINT *interface_index);
+
+/* APIs for packet pool. */
+UINT nx_packet_allocate(NX_PACKET_POOL *pool_ptr,  NX_PACKET **packet_ptr,
+                        ULONG packet_type, ULONG wait_option);
+UINT nx_packet_copy(NX_PACKET *packet_ptr, NX_PACKET **new_packet_ptr,
+                    NX_PACKET_POOL *pool_ptr, ULONG wait_option);
+UINT nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size,
+                           NX_PACKET_POOL *pool_ptr, ULONG wait_option);
+UINT nx_packet_data_extract_offset(NX_PACKET *packet_ptr, ULONG offset, VOID *buffer_start,
+                                   ULONG buffer_length, ULONG *bytes_copied);
+UINT nx_packet_data_retrieve(NX_PACKET *packet_ptr, VOID *buffer_start, ULONG *bytes_copied);
+UINT nx_packet_length_get(NX_PACKET *packet_ptr, ULONG *length);
+#ifndef NX_DISABLE_ERROR_CHECKING
+UINT _nxe_packet_pool_create(NX_PACKET_POOL *pool_ptr, CHAR *name, ULONG payload_size,
+                             VOID *memory_ptr, ULONG memory_size, UINT pool_control_block_size);
+#else
+UINT _nx_packet_pool_create(NX_PACKET_POOL *pool_ptr, CHAR *name, ULONG payload_size,
+                            VOID *memory_ptr, ULONG memory_size);
+#endif
+UINT nx_packet_pool_delete(NX_PACKET_POOL *pool_ptr);
+UINT nx_packet_pool_info_get(NX_PACKET_POOL *pool_ptr, ULONG *total_packets, ULONG *free_packets,
+                             ULONG *empty_pool_requests, ULONG *empty_pool_suspensions,
+                             ULONG *invalid_packet_releases);
+UINT nx_packet_pool_low_watermark_set(NX_PACKET_POOL *pool_ptr, ULONG low_water_mark);
+#ifndef NX_DISABLE_ERROR_CHECKING
+UINT _nxe_packet_release(NX_PACKET **packet_ptr_ptr);
+UINT _nxe_packet_transmit_release(NX_PACKET **packet_ptr_ptr);
+#else
+UINT _nx_packet_release(NX_PACKET *packet_ptr);
+UINT _nx_packet_transmit_release(NX_PACKET *packet_ptr);
+#endif
+UINT nx_packet_vlan_priority_set(NX_PACKET *packet_ptr, UINT vlan_priority);
+
+/* APIs for RARP. */
+UINT nx_rarp_disable(NX_IP *ip_ptr);
+UINT nx_rarp_enable(NX_IP *ip_ptr);
+UINT nx_rarp_info_get(NX_IP *ip_ptr, ULONG *rarp_requests_sent, ULONG *rarp_responses_received,
+                      ULONG *rarp_invalid_messages);
+
+/* APIs for TCP. */
+UINT nx_tcp_client_socket_bind(NX_TCP_SOCKET *socket_ptr, UINT port, ULONG wait_option);
+UINT nx_tcp_client_socket_connect(NX_TCP_SOCKET *socket_ptr, ULONG server_ip,
+                                  UINT server_port, ULONG wait_option);
+UINT nx_tcp_client_socket_port_get(NX_TCP_SOCKET *socket_ptr, UINT *port_ptr);
+UINT nx_tcp_client_socket_unbind(NX_TCP_SOCKET *socket_ptr);
+UINT nx_tcp_enable(NX_IP *ip_ptr);
+UINT nx_tcp_free_port_find(NX_IP *ip_ptr, UINT port, UINT *free_port_ptr);
+UINT nx_tcp_info_get(NX_IP *ip_ptr, ULONG *tcp_packets_sent, ULONG *tcp_bytes_sent,
+                     ULONG *tcp_packets_received, ULONG *tcp_bytes_received,
+                     ULONG *tcp_invalid_packets, ULONG *tcp_receive_packets_dropped,
+                     ULONG *tcp_checksum_errors, ULONG *tcp_connections,
+                     ULONG *tcp_disconnections, ULONG *tcp_connections_dropped,
+                     ULONG *tcp_retransmit_packets);
+UINT nx_tcp_server_socket_accept(NX_TCP_SOCKET *socket_ptr, ULONG wait_option);
+UINT nx_tcp_server_socket_listen(NX_IP *ip_ptr, UINT port, NX_TCP_SOCKET *socket_ptr, UINT listen_queue_size,
+                                 VOID (*tcp_listen_callback)(NX_TCP_SOCKET *socket_ptr, UINT port));
+UINT nx_tcp_server_socket_relisten(NX_IP *ip_ptr, UINT port, NX_TCP_SOCKET *socket_ptr);
+UINT nx_tcp_server_socket_unaccept(NX_TCP_SOCKET *socket_ptr);
+UINT nx_tcp_server_socket_unlisten(NX_IP *ip_ptr, UINT port);
+UINT nx_tcp_socket_bytes_available(NX_TCP_SOCKET *socket_ptr, ULONG *bytes_available);
+#ifndef NX_DISABLE_ERROR_CHECKING
+UINT _nxe_tcp_socket_create(NX_IP *ip_ptr, NX_TCP_SOCKET *socket_ptr, CHAR *name,
+                            ULONG type_of_service, ULONG fragment, UINT time_to_live, ULONG window_size,
+                            VOID (*tcp_urgent_data_callback)(NX_TCP_SOCKET *socket_ptr),
+                            VOID (*tcp_disconnect_callback)(NX_TCP_SOCKET *socket_ptr),
+                            UINT tcp_socket_size);
+#else
+UINT _nx_tcp_socket_create(NX_IP *ip_ptr, NX_TCP_SOCKET *socket_ptr, CHAR *name,
+                           ULONG type_of_service, ULONG fragment, UINT time_to_live, ULONG window_size,
+                           VOID (*tcp_urgent_data_callback)(NX_TCP_SOCKET *socket_ptr),
+                           VOID (*tcp_disconnect_callback)(NX_TCP_SOCKET *socket_ptr));
+#endif
+UINT nx_tcp_socket_delete(NX_TCP_SOCKET *socket_ptr);
+UINT nx_tcp_socket_disconnect(NX_TCP_SOCKET *socket_ptr, ULONG wait_option);
+UINT nx_tcp_socket_disconnect_complete_notify(NX_TCP_SOCKET *socket_ptr,
+                                              VOID (*tcp_disconnect_complete_notify)(NX_TCP_SOCKET *));
+UINT nx_tcp_socket_establish_notify(NX_TCP_SOCKET *socket_ptr,
+                                    VOID (*tcp_establish_notify)(NX_TCP_SOCKET *));
+UINT nx_tcp_socket_info_get(NX_TCP_SOCKET *socket_ptr, ULONG *tcp_packets_sent, ULONG *tcp_bytes_sent,
+                            ULONG *tcp_packets_received, ULONG *tcp_bytes_received,
+                            ULONG *tcp_retransmit_packets, ULONG *tcp_packets_queued,
+                            ULONG *tcp_checksum_errors, ULONG *tcp_socket_state,
+                            ULONG *tcp_transmit_queue_depth, ULONG *tcp_transmit_window,
+                            ULONG *tcp_receive_window);
+UINT nx_tcp_socket_mss_get(NX_TCP_SOCKET *socket_ptr, ULONG *mss);
+UINT nx_tcp_socket_mss_peer_get(NX_TCP_SOCKET *socket_ptr, ULONG *peer_mss);
+UINT nx_tcp_socket_mss_set(NX_TCP_SOCKET *socket_ptr, ULONG mss);
+UINT nx_tcp_socket_peer_info_get(NX_TCP_SOCKET *socket_ptr, ULONG *peer_ip_address, ULONG *peer_port);
+UINT nx_tcp_socket_queue_depth_notify_set(NX_TCP_SOCKET *socket_ptr,
+                                          VOID (*tcp_socket_queue_depth_notify)(NX_TCP_SOCKET *));
+UINT nx_tcp_socket_receive(NX_TCP_SOCKET *socket_ptr, NX_PACKET **packet_ptr, ULONG wait_option);
+UINT nx_tcp_socket_receive_notify(NX_TCP_SOCKET *socket_ptr,
+                                  VOID (*tcp_receive_notify)(NX_TCP_SOCKET *));
+UINT nx_tcp_socket_receive_queue_max_set(NX_TCP_SOCKET *socket_ptr, UINT receive_queue_maximum);
+#ifndef NX_DISABLE_ERROR_CHECKING
+UINT _nxe_tcp_socket_send(NX_TCP_SOCKET *socket_ptr, NX_PACKET **packet_ptr_ptr, ULONG wait_option);
+#else
+UINT _nx_tcp_socket_send(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr, ULONG wait_option);
+#endif
+UINT nx_tcp_socket_state_wait(NX_TCP_SOCKET *socket_ptr, UINT desired_state, ULONG wait_option);
+UINT nx_tcp_socket_timed_wait_callback(NX_TCP_SOCKET *socket_ptr,
+                                       VOID (*tcp_timed_wait_callback)(NX_TCP_SOCKET *));
+UINT nx_tcp_socket_transmit_configure(NX_TCP_SOCKET *socket_ptr, ULONG max_queue_depth, ULONG timeout,
+                                      ULONG max_retries, ULONG timeout_shift);
+UINT nx_tcp_socket_window_update_notify_set(NX_TCP_SOCKET *socket_ptr,
+                                            VOID (*tcp_window_update_notify)(NX_TCP_SOCKET *));
+UINT nx_tcp_socket_vlan_priority_set(NX_TCP_SOCKET *socket_ptr, UINT vlan_priority);
+UINT nxd_tcp_client_socket_connect(NX_TCP_SOCKET *socket_ptr, NXD_ADDRESS *server_ip,
+                                   UINT server_port, ULONG wait_option);
+UINT nxd_tcp_socket_peer_info_get(NX_TCP_SOCKET *socket_ptr, NXD_ADDRESS *peer_ip_address, ULONG *peer_port);
+
+/* APIs for UDP. */
+UINT nx_udp_enable(NX_IP *ip_ptr);
+UINT nx_udp_free_port_find(NX_IP *ip_ptr, UINT port, UINT *free_port_ptr);
+UINT nx_udp_info_get(NX_IP *ip_ptr, ULONG *udp_packets_sent, ULONG *udp_bytes_sent,
+                     ULONG *udp_packets_received, ULONG *udp_bytes_received,
+                     ULONG *udp_invalid_packets, ULONG *udp_receive_packets_dropped,
+                     ULONG *udp_checksum_errors);
+UINT nx_udp_packet_info_extract(NX_PACKET *packet_ptr, ULONG *ip_address, UINT *protocol, UINT *port, UINT *interface_index);
+UINT nx_udp_socket_bind(NX_UDP_SOCKET *socket_ptr, UINT  port, ULONG wait_option);
+UINT nx_udp_socket_bytes_available(NX_UDP_SOCKET *socket_ptr, ULONG *bytes_available);
+UINT nx_udp_socket_checksum_disable(NX_UDP_SOCKET *socket_ptr);
+UINT nx_udp_socket_checksum_enable(NX_UDP_SOCKET *socket_ptr);
+#ifndef NX_DISABLE_ERROR_CHECKING
+UINT _nxe_udp_socket_create(NX_IP *ip_ptr, NX_UDP_SOCKET *socket_ptr, CHAR *name,
+                            ULONG type_of_service, ULONG fragment, UINT time_to_live,
+                            ULONG queue_maximum, UINT udp_socket_size);
+#else
+
+UINT _nx_udp_socket_create(NX_IP *ip_ptr, NX_UDP_SOCKET *socket_ptr, CHAR *name,
+                           ULONG type_of_service, ULONG fragment, UINT time_to_live,
+                           ULONG queue_maximum);
+#endif
+UINT nx_udp_socket_delete(NX_UDP_SOCKET *socket_ptr);
+UINT nx_udp_socket_info_get(NX_UDP_SOCKET *socket_ptr, ULONG *udp_packets_sent, ULONG *udp_bytes_sent,
+                            ULONG *udp_packets_received, ULONG *udp_bytes_received, ULONG *udp_packets_queued,
+                            ULONG *udp_receive_packets_dropped, ULONG *udp_checksum_errors);
+UINT nx_udp_socket_port_get(NX_UDP_SOCKET *socket_ptr, UINT *port_ptr);
+UINT nx_udp_socket_receive(NX_UDP_SOCKET *socket_ptr, NX_PACKET **packet_ptr, ULONG wait_option);
+UINT nx_udp_socket_receive_notify(NX_UDP_SOCKET *socket_ptr,
+                                  VOID (*udp_receive_notify)(NX_UDP_SOCKET *));
+#ifndef NX_DISABLE_ERROR_CHECKING
+UINT _nxde_udp_socket_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET **packet_ptr,
+                           NXD_ADDRESS *ip_address, UINT port);
+UINT _nxde_udp_socket_source_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
+                                  NXD_ADDRESS *ip_address, UINT port, UINT address_index);
+
+#else /* NX_DISABLE_ERROR_CHECKING */
+UINT _nxd_udp_socket_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
+                          NXD_ADDRESS *ip_address, UINT port);
+UINT _nxd_udp_socket_source_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
+                                 NXD_ADDRESS *ip_address, UINT port, UINT address_index);
+#endif /* NX_DISABLE_ERROR_CHECKING */
+UINT nx_udp_socket_unbind(NX_UDP_SOCKET *socket_ptr);
+UINT nx_udp_source_extract(NX_PACKET *packet_ptr, ULONG *ip_address, UINT *port);
+UINT nx_udp_socket_vlan_priority_set(NX_UDP_SOCKET *socket_ptr, UINT vlan_priority);
+UINT nxd_udp_source_extract(NX_PACKET *packet_ptr, NXD_ADDRESS *ip_address, UINT *port);
+#ifndef NX_DISABLE_ERROR_CHECKING
+UINT _nxe_udp_socket_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET **packet_ptr_ptr,
+                          ULONG ip_address, UINT port);
+UINT _nxe_udp_socket_source_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET **packet_ptr,
+                                 ULONG ip_address, UINT port, UINT address_index);
+#else
+UINT _nx_udp_socket_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
+                         ULONG ip_address, UINT port);
+UINT _nx_udp_socket_source_send(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
+                                ULONG ip_address, UINT port, UINT address_index);
+
+#endif
+UINT nxd_udp_packet_info_extract(NX_PACKET *packet_ptr, NXD_ADDRESS *ip_address,
+                                 UINT *protocol, UINT *port, UINT *interface_index);
+
+/* APIs for others. */
+VOID nx_system_initialize(VOID);
+UINT nx_http_proxy_client_enable(NX_IP *ip_ptr, NXD_ADDRESS *proxy_server_ip, UINT proxy_server_port,
+                                 UCHAR *username, UINT username_length, UCHAR *password, UINT password_length);
+
+/* Define several function prototypes for exclusive use by NetX I/O drivers.  These routines
+   are used by NetX drivers to report received packets to NetX.  */
+
+/* Define the driver deferred packet routines.  Using these routines results in the lowest
+   possible ISR processing time.  However, it does require slightly more overhead than the
+   other NetX receive processing routines.  The _nx_ip_driver_deferred_enable routine
+   should be called from the driver's initialization routine, with the driver's deferred
+   packet processing routine provided.  Each packet the driver receives should be
+   delivered to NetX via the _nx_ip_driver_deferred_receive function.  This function
+   queues the packet for the NetX IP thread.  The NetX IP thread will then call the driver's
+   deferred packet processing routine, which can then process the packet at a thread level
+   of execution.  The deferred packet processing routine should use the _nx_ip_packet_receive,
+   _nx_arp_packet_deferred_receive, and _nx_rarp_packet_deferred_receive to dispatch the
+   appropriate packets to NetX.  In order to use the deferred packet processing, NetX
+   must be built with NX_DRIVER_DEFERRED_PROCESSING defined.  */
+
+VOID _nx_ip_driver_deferred_enable(NX_IP *ip_ptr, VOID (*driver_deferred_packet_handler)(NX_IP *ip_ptr, NX_PACKET *packet_ptr));
+VOID _nx_ip_driver_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
+
+
+/* Define the driver deferred processing notification routine. Calling this routine from
+   the driver will cause the driver to be called with the NX_LINK_DEFERRED_PROCESSING
+   value specified in the nx_ip_driver_command field of the NX_IP_DRIVER request
+   structure. This is useful in situations where the driver wishes to process activities
+   like transmit complete interrupts at the thread level rather than in the ISR. Note
+   that the driver must set its own internal variables in order to know what processing
+   needs to be done when subsequently called from the IP helper thread. */
+
+VOID _nx_ip_driver_deferred_processing(NX_IP *ip_ptr);
+
+
+/* Define the deferred NetX receive processing routines.  These routines depend on the
+   NetX I/O drive to perform enough processing in the ISR to strip the link protocol
+   header and dispatch to the appropriate NetX receive processing.  These routines
+   can also be called from the previously mentioned driver deferred processing.  */
+
+VOID _nx_ip_packet_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
+VOID _nx_arp_packet_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
+VOID _nx_rarp_packet_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
+
+
+/* Define the direct IP packet receive processing.  This is the lowest overhead way
+   to notify NetX of a received IP packet, however, it results in the most amount of
+   processing in the driver's receive ISR.  If the driver deferred packet processing
+   is used, this routine should be used to notify NetX of the newly received IP packet.  */
+
+VOID _nx_ip_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr);
+
+/* Define the direct link status event.  This is the lowest overhead way
+   to notify NetX of link status event, however, it results in the most amount of
+   processing in the driver's receive ISR.  */
+VOID _nx_ip_driver_link_status_event(NX_IP *ip_ptr, UINT interface_index);
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+/* Define the direct TCP packet receive processing.  This is used with TCP/IP offload feature.  */
+VOID _nx_tcp_socket_driver_packet_receive(NX_TCP_SOCKET *socket_ptr, NX_PACKET *packet_ptr);
+
+/* Define the direct TCP established processing.  This is used with TCP/IP offload feature.  */
+UINT _nx_tcp_socket_driver_establish(NX_TCP_SOCKET *socket_ptr, NX_INTERFACE *interface_ptr, UINT remote_port);
+
+/* Define the direct UDP packet receive processing.  This is used with TCP/IP offload feature.  */
+VOID _nx_udp_socket_driver_packet_receive(NX_UDP_SOCKET *socket_ptr, NX_PACKET *packet_ptr,
+                                          NXD_ADDRESS *local_ip, NXD_ADDRESS *remote_ip, UINT remote_port);
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+#endif
+
+#ifdef FEATURE_NX_IPV6
+
+#ifdef NX_LITTLE_ENDIAN
+#define NX_IPV6_ADDRESS_CHANGE_ENDIAN(addr) _nx_ipv6_address_change_endian(addr)
+#else /* BIG ENDIAN */
+#define NX_IPV6_ADDRESS_CHANGE_ENDIAN(addr)
+#endif /* NX_LITTLE_ENDIAN */
+
+#endif /* FEATURE_NX_IPV6 */
+
+
+#ifdef NX_IPV6_UTIL_INLINE
+/* Return 1 if IPv6 address is unspecified (::)  */
+#define CHECK_UNSPECIFIED_ADDRESS(ip_addr) \
+    (!((ip_addr)[0] || (ip_addr)[1] || (ip_addr)[2] || (ip_addr)[3]))
+
+
+/* Set IPv6 address to unspecified (::) */
+#define SET_UNSPECIFIED_ADDRESS(ip_addr) \
+    do {                                 \
+        (ip_addr)[0] = 0;                \
+        (ip_addr)[1] = 0;                \
+        (ip_addr)[2] = 0;                \
+        (ip_addr)[3] = 0;                \
+    } while (0)
+
+
+/* Copy IPv6 address. */
+#define COPY_IPV6_ADDRESS(copy_from, copy_to) \
+    do {                                      \
+        (copy_to)[0] = (copy_from)[0];        \
+        (copy_to)[1] = (copy_from)[1];        \
+        (copy_to)[2] = (copy_from)[2];        \
+        (copy_to)[3] = (copy_from)[3];        \
+    } while (0)
+
+/* Copy NXD IP address structure  */
+#define COPY_NXD_ADDRESS(copy_from, copy_to)                                     \
+    do {                                                                         \
+        (copy_to) -> nxd_ip_version       = (copy_from) -> nxd_ip_version;       \
+        (copy_to) -> nxd_ip_address.v6[0] = (copy_from) -> nxd_ip_address.v6[0]; \
+        (copy_to) -> nxd_ip_address.v6[1] = (copy_from) -> nxd_ip_address.v6[1]; \
+        (copy_to) -> nxd_ip_address.v6[2] = (copy_from) -> nxd_ip_address.v6[2]; \
+        (copy_to) -> nxd_ip_address.v6[3] = (copy_from) -> nxd_ip_address.v6[3]; \
+    } while (0)
+
+
+#define SET_SOLICITED_NODE_MULTICAST_ADDRESS(address, unicast) \
+    do {                                                       \
+        (address)[0] = 0xFF020000;                             \
+        (address)[1] = 0;                                      \
+        (address)[2] = 1;                                      \
+        (address)[3] = 0xFF000000 | (unicast)[3];              \
+    } while (0)
+
+
+#define CHECK_ALL_ROUTER_MCAST_ADDRESS(addr) \
+    (((addr)[0] == 0xFF020000) &&            \
+     ((addr)[1] == 0)          &&            \
+     ((addr)[2] == 0)          &&            \
+     ((addr)[3] == 2))
+
+/* Check whether or not two IPv6 addresses are the same. */
+#define CHECK_IPV6_ADDRESSES_SAME(addr1, addr2) \
+    (((addr1)[0] == (addr2)[0]) &&              \
+     ((addr1)[1] == (addr2)[1]) &&              \
+     ((addr1)[2] == (addr2)[2]) &&              \
+     ((addr1)[3] == (addr2)[3]))
+
+
+#endif /* NX_IPV6_UTIL_INLINE */
+
+/* Utility functions.  */
+UINT _nx_utility_string_length_check(CHAR *input_string, UINT *string_length, UINT max_string_length);
+UINT _nx_utility_string_to_uint(CHAR *input_string, UINT string_length, UINT *number);
+UINT _nx_utility_uint_to_string(UINT number, UINT base, CHAR *string_buffer, UINT string_buffer_size);
+UINT _nx_utility_base64_encode(UCHAR *name, UINT name_size, UCHAR *base64name, UINT base64name_size, UINT *bytes_copied);
+UINT _nx_utility_base64_decode(UCHAR *base64name, UINT base64name_size, UCHAR *name, UINT name_size, UINT *bytes_copied);
+
+/* Determine if a C++ compiler is being used.  If so, complete the standard
+   C conditional started above.  */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv4_send_error_message.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv4_send_error_message.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv4_send_error_message.c	(revision 69)
@@ -0,0 +1,338 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Control Message Protocol (ICMPv4)                          */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_packet.h"
+#include "nx_ip.h"
+#include "nx_icmp.h"
+
+#ifdef NX_IPSEC_ENABLE
+#include "nx_ipsec.h"
+#endif /* NX_IPSEC_ENABLE */
+
+#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_ICMPV4_ERROR_MESSAGE)
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_icmpv4_send_error_message                      PORTABLE C       */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function is called by various IPv4 components to send an       */
+/*    error message when necessary.                                       */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                IP stack instance             */
+/*    offending_packet                      The packet that caused the    */
+/*                                              error.                    */
+/*    word1                                 ICMPv4 error message header   */
+/*                                              field, progarmmed by      */
+/*                                              the caller.               */
+/*    error_pointer                         Pointer to the byte that      */
+/*                                              caused the error          */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ip_checksum_compute               Computer ICMP checksum        */
+/*    _nx_ip_packet_send                    Send ICMP packet out          */
+/*    _nx_packet_allocate                   Packet allocate               */
+/*    _nx_packet_release                    Release packet back to pool   */
+/*    _nx_ip_route_find                     Find outgoing interface for   */
+/*                                             sending packet             */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID _nx_icmpv4_send_error_message(NX_IP *ip_ptr, NX_PACKET *offending_packet,
+                                   ULONG word1, ULONG error_pointer)
+{
+
+NX_PACKET       *pkt_ptr;
+USHORT           checksum;
+#if defined(NX_DISABLE_ICMPV4_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
+UINT             compute_checksum = 1;
+#endif /* defined(NX_DISABLE_ICMPV4_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
+NX_ICMPV4_ERROR *icmpv4_error;
+NX_IPV4_HEADER  *ip_header_ptr;
+UINT             ip_header_size;
+UINT             bytes_to_copy, i;
+ULONG            src_ip;
+ULONG            next_hop_address = NX_NULL;
+ULONG           *src_packet, *dest_packet;
+NX_INTERFACE    *if_ptr;
+
+#ifdef NX_IPSEC_ENABLE
+VOID            *sa = NX_NULL;
+UINT             ret = 0;
+ULONG            data_offset;
+NXD_ADDRESS      src_addr;
+NXD_ADDRESS      dest_addr;
+#endif /* NX_IPSEC_ENABLE */
+
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, offending_packet);
+
+    /* Do not send ICMPv4 error message if ICMPv4 is not enabled. */
+    if (ip_ptr -> nx_ip_icmpv4_packet_process == NX_NULL)
+    {
+        return;
+    }
+
+    /* Find out the source and destination IP addresses of the offending packet. */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    ip_header_ptr = (NX_IPV4_HEADER *)(offending_packet -> nx_packet_ip_header);
+    src_ip = ip_header_ptr -> nx_ip_header_source_ip;
+
+    /* Get the incoming interface. */
+    if_ptr = offending_packet -> nx_packet_address.nx_packet_interface_ptr;
+
+    /* An ICMP error message MUST NOT be sent as the result of receiving:
+       RFC1122, Section3.2.2, Page39.  */
+
+    /* A datagram destined to an IP broadcast or IP multicast address.  */
+    if ((ip_header_ptr -> nx_ip_header_destination_ip == NX_IP_LIMITED_BROADCAST) ||
+        ((ip_header_ptr -> nx_ip_header_destination_ip & NX_IP_CLASS_D_MASK) == NX_IP_CLASS_D_TYPE))
+    {
+        return;
+    }
+
+    /* A datagram sent as a link-layer broadcast.  */
+    if (((ip_header_ptr -> nx_ip_header_destination_ip & if_ptr -> nx_interface_ip_network_mask) ==
+         if_ptr -> nx_interface_ip_network) &&
+        ((ip_header_ptr -> nx_ip_header_destination_ip & ~(if_ptr -> nx_interface_ip_network_mask)) ==
+         ~(if_ptr -> nx_interface_ip_network_mask)))
+    {
+        return;
+    }
+
+    /* A non-initial fragment.  */
+    if (ip_header_ptr -> nx_ip_header_word_1 & NX_IP_OFFSET_MASK)
+    {
+        return;
+    }
+
+    /* A datagram whose source address does not define a single host,
+       e.g., a zero address, a loopback address, a broadcast address,
+       a multicast address, or a Class E address.  */
+    if ((ip_header_ptr -> nx_ip_header_source_ip == 0) ||
+        ((ip_header_ptr -> nx_ip_header_source_ip >= NX_IP_LOOPBACK_FIRST) &&
+         (ip_header_ptr -> nx_ip_header_source_ip <= NX_IP_LOOPBACK_LAST)) ||
+        (ip_header_ptr -> nx_ip_header_source_ip == NX_IP_LIMITED_BROADCAST) ||
+        ((ip_header_ptr -> nx_ip_header_source_ip & NX_IP_CLASS_D_MASK) == NX_IP_CLASS_D_TYPE))
+    {
+        return;
+    }
+
+    /* Allocate a packet to build the ICMPv4 error message in.  */
+    if (_nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &pkt_ptr, NX_IPv4_ICMP_PACKET, NX_NO_WAIT))
+    {
+
+        /* Error getting packet, so just get out!  */
+        return;
+    }
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, pkt_ptr);
+
+    /* Mark the packet as IPv4. */
+    /*lint -e{644} suppress variable might not be initialized, since "pkt_ptr" was initialized in _nx_packet_allocate. */
+    pkt_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4;
+
+    /* Size of the message is ICMPv4 */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    icmpv4_error = (NX_ICMPV4_ERROR *)(pkt_ptr -> nx_packet_prepend_ptr);
+    icmpv4_error -> nx_icmpv4_error_header.nx_icmpv4_header_type = (UCHAR)((word1 >> 24) & 0xFF);
+    icmpv4_error -> nx_icmpv4_error_header.nx_icmpv4_header_code = (UCHAR)((word1 >> 16) & 0xFF);
+    icmpv4_error -> nx_icmpv4_error_header.nx_icmpv4_header_checksum = 0;
+    icmpv4_error -> nx_icmpv4_error_pointer = (error_pointer << 24);
+
+    /* Change to network byte order. */
+    NX_CHANGE_ULONG_ENDIAN(icmpv4_error -> nx_icmpv4_error_pointer);
+
+    /* IP Header + 64 bits (64 bits = 2 ULONGs) of Data Datagram.  */
+    ip_header_size = ((ip_header_ptr -> nx_ip_header_word_0 & 0x0F000000) >> 24);
+    bytes_to_copy = (UINT)((ip_header_size + 2) * sizeof(ULONG));
+
+    /* Set the packet length and pointers.  The length will be increased to include
+       the IPv4 header in the IP send function.  The Prepend function will be similarly
+       updated in the IP send function. */
+    pkt_ptr -> nx_packet_length = bytes_to_copy + (ULONG)sizeof(NX_ICMPV4_ERROR);
+    pkt_ptr -> nx_packet_append_ptr = pkt_ptr -> nx_packet_prepend_ptr + pkt_ptr -> nx_packet_length;
+
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    src_packet  = (ULONG *)(offending_packet -> nx_packet_ip_header);
+
+    /*lint -e{923} suppress cast between pointer and ULONG, since it is necessary  */
+    dest_packet = (ULONG *)NX_UCHAR_POINTER_ADD(icmpv4_error, sizeof(NX_ICMPV4_ERROR));
+
+    /* Endian swap the incoming IPv4 normal header to network byte order. */
+    for (i = 0; i < NX_IP_NORMAL_LENGTH; i++)
+    {
+        NX_CHANGE_ULONG_ENDIAN(*src_packet);
+        src_packet++;
+    }
+
+    /* Reset the packet pointer to the received packet IP header. */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    src_packet  = (ULONG *)(offending_packet -> nx_packet_ip_header);
+
+    /* Copy the data from the received packet to the ICMPv4 error packet. */
+    for (; bytes_to_copy > 0; bytes_to_copy -= 4)
+    {
+
+        *dest_packet++ = *src_packet++;
+    }
+
+    /* Get the IP header pointer.  */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    src_packet  = (ULONG *)(offending_packet -> nx_packet_ip_header);
+
+    /* Endian swap the IPv4 normal header back to host byte order. */
+    for (i = 0; i < NX_IP_NORMAL_LENGTH; i++)
+    {
+        NX_CHANGE_ULONG_ENDIAN(*src_packet);
+        src_packet++;
+    }
+
+    /* Use the corresponding interface address as sender's address. */
+    pkt_ptr -> nx_packet_address.nx_packet_interface_ptr = offending_packet -> nx_packet_address.nx_packet_interface_ptr;
+
+    /* Figure out the best interface to send the ICMP packet on. */
+    _nx_ip_route_find(ip_ptr, src_ip,
+                      &pkt_ptr -> nx_packet_address.nx_packet_interface_ptr,
+                      &next_hop_address);
+
+#ifdef NX_IPSEC_ENABLE
+
+    /* Check for possible SA match. */
+    if (ip_ptr -> nx_ip_packet_egress_sa_lookup != NX_NULL)               /* IPsec is enabled. */
+    {
+
+        /* Set up IP address. */
+        src_addr.nxd_ip_version = NX_IP_VERSION_V4;
+        src_addr.nxd_ip_address.v4 = pkt_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_ip_address;
+        dest_addr.nxd_ip_version = NX_IP_VERSION_V4;
+        dest_addr.nxd_ip_address.v4 = src_ip;
+
+        /* If the SA has not been set. */
+        ret = ip_ptr -> nx_ip_packet_egress_sa_lookup(ip_ptr,                 /* IP ptr */
+                                                      &src_addr,              /* src_addr */
+                                                      &dest_addr,             /* dest_addr */
+                                                      NX_PROTOCOL_ICMP,       /* protocol */
+                                                      0,                      /* src_port */
+                                                      0,                      /* dest_port */
+                                                      &data_offset, &sa,
+                                                      ((word1 >> 16) & 0xFFFF));
+        if (ret == NX_IPSEC_TRAFFIC_BYPASS)
+        {
+            sa = NX_NULL;
+            data_offset = 0;
+        }
+        else if (ret == NX_IPSEC_TRAFFIC_DROP || ret == NX_IPSEC_TRAFFIC_PENDING_IKEV2)
+        {
+
+            /* IPSec SA disallows this packet. Drop the packet and return. */
+            _nx_packet_release(pkt_ptr);
+
+            return;
+        }
+    }
+
+    pkt_ptr -> nx_packet_ipsec_sa_ptr = sa;
+
+#endif /* NX_IPSEC_ENABLE */
+
+#ifdef NX_DISABLE_ICMPV4_TX_CHECKSUM
+    compute_checksum = 0;
+#endif /* NX_DISABLE_ICMPV4_TX_CHECKSUM */
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    if (pkt_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM)
+    {
+        compute_checksum = 0;
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+#ifdef NX_IPSEC_ENABLE
+    if ((sa != NX_NULL) && (((NX_IPSEC_SA *)sa) -> nx_ipsec_sa_encryption_method != NX_CRYPTO_NONE))
+    {
+        compute_checksum = 1;
+    }
+#endif /* NX_IPSEC_ENABLE */
+#if defined(NX_DISABLE_ICMPV4_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
+    if (compute_checksum)
+#endif /* defined(NX_DISABLE_ICMPV4_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
+    {
+
+        /* Compute the checksum of the ICMP packet.  */
+        checksum = _nx_ip_checksum_compute(pkt_ptr, NX_IP_ICMP,
+                                           (UINT)pkt_ptr -> nx_packet_length,
+                                           /* ICMPV4 checksum does not include
+                                              src/dest addresses */
+                                           NX_NULL, NX_NULL);
+
+        icmpv4_error -> nx_icmpv4_error_header.nx_icmpv4_header_checksum = (USHORT)(~checksum);
+
+        /* Swap to network byte order. */
+        NX_CHANGE_USHORT_ENDIAN(icmpv4_error -> nx_icmpv4_error_header.nx_icmpv4_header_checksum);
+    }
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    else
+    {
+        pkt_ptr -> nx_packet_interface_capability_flag |= NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM;
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+    /* Send the ICMP packet to the IP component. The time to live is set to 255.  */
+    /*lint -e{644} suppress variable might not be initialized, since "next_hop_address" was initialized in _nx_ip_route_find. */
+    _nx_ip_packet_send(ip_ptr, pkt_ptr, src_ip,
+                       NX_IP_NORMAL, 255, NX_IP_ICMP, NX_FRAGMENT_OKAY, next_hop_address);
+
+    return;
+}
+#endif /* !NX_DISABLE_IPV4 && !NX_DISABLE_ICMPV4_ERROR_MESSAGE  */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_DAD_clear_NDCache_entry.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_DAD_clear_NDCache_entry.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_DAD_clear_NDCache_entry.c	(revision 69)
@@ -0,0 +1,93 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Control Message Protocol (ICMP)                            */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_nd_cache.h"
+#include "nx_icmpv6.h"
+
+
+#ifdef FEATURE_NX_IPV6
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_icmp_DAD_clear_NDCache_entry                    PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to the IP instance    */
+/*    ip_addr                               Neighbor IPv6 address of cache*/
+/*                                             entry to delete            */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    tx_mutex_get                        Obtain exclusive lock (on table)*/
+/*    tx_mutex_put                        Release exclusive lock          */
+/*    _nx_nd_cache_find_entry             Find cache entry by IP address  */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_icmpv6_perform_DAD              Verify IPv6 address is unique   */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+void _nx_icmpv6_DAD_clear_NDCache_entry(NX_IP *ip_ptr, ULONG *ip_addr)
+{
+
+ND_CACHE_ENTRY *NDCacheEntry;
+
+    /* Find the ND CACHE entry.  */
+    if (_nx_nd_cache_find_entry(ip_ptr, ip_addr, &NDCacheEntry) == NX_SUCCESS)
+    {
+
+        /*lint -e{644} suppress variable might not be initialized, since "NDCacheEntry" was initialized in _nx_nd_cache_find_entry. */
+        NDCacheEntry -> nx_nd_cache_nd_status = ND_CACHE_STATE_INVALID;
+    }
+
+    return;
+}
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_dest_table_add.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_dest_table_add.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_dest_table_add.c	(revision 69)
@@ -0,0 +1,253 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Control Message Protocol (ICMP)                            */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_icmpv6.h"
+
+#ifdef FEATURE_NX_IPV6
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_icmpv6_dest_table_add                           PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function searches for a matching destination in the table entry*/
+/*    and if no match is found, it creates one.  If a match is            */
+/*    found, the next hop field is updated if the data is changed, and a  */
+/*    pointer returned to that entry. If path MTU discovery is enabled,   */
+/*    the path MTU and time out are set to supplied values.  If none are  */
+/*    NetX Duo applies default values.                                    */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                               IP interface thread task       */
+/*    destination_address                  Destination IP address.        */
+/*    dest_entry_ptr                       Pointer to location of matching*/
+/*                                           table entry, if any          */
+/*    next_hop                             Pointer to next hop address    */
+/*    path_mtu                             Optional path mtu update.      */
+/*                                           Note: caller shall make sure */
+/*                                           MTU does not exceed physical */
+/*                                           link MTU size.               */
+/*    mtu_timeout                          Optional entry timeout update  */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS                           Found matching entry           */
+/*    NX_NOT_SUCCESSFUL                    Error searching table          */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    tx_mutex_get                         Obtain destination table lock  */
+/*    tx_mutex_put                         Release destination table lock */
+/*    memset                               Clear memory block             */
+/*    _nx_nd_cache_find_entry              Find next hop in the ND cache  */
+/*    _nx_nd_cache_add_entry               Create an entry in ND cache    */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+
+UINT _nx_icmpv6_dest_table_add(NX_IP *ip_ptr, ULONG *destination_address,
+                               NX_IPV6_DESTINATION_ENTRY **dest_entry_ptr, ULONG *next_hop,
+                               ULONG path_mtu, ULONG mtu_timeout, NXD_IPV6_ADDRESS *ipv6_address)
+{
+
+UINT i, table_size;
+UINT status;
+
+    /* Pointers must not be NULL. */
+    NX_ASSERT((destination_address != NX_NULL) && (dest_entry_ptr != NX_NULL) && (next_hop != NX_NULL));
+
+    /* Check if destination table already exist. */
+    status = _nx_icmpv6_dest_table_find(ip_ptr, destination_address, dest_entry_ptr, path_mtu, mtu_timeout);
+
+    /* Check status.  */
+    if (status == NX_SUCCESS)
+    {
+
+        /* Check if the next hop address is same.  */
+        if (CHECK_IPV6_ADDRESSES_SAME(next_hop, (*dest_entry_ptr) -> nx_ipv6_destination_entry_next_hop))
+        {
+
+            /* Same next hop address. Return success.  */
+            return(NX_SUCCESS);
+        }
+        else
+        {
+
+#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
+            /* Get MTU from original destination table. */
+            path_mtu = (*dest_entry_ptr) -> nx_ipv6_destination_entry_path_mtu;
+            mtu_timeout = (*dest_entry_ptr) -> nx_ipv6_destination_entry_MTU_timer_tick;
+#endif /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
+
+            /* Next hop is different. Delete this destination table and add new entry.  */
+            (*dest_entry_ptr) -> nx_ipv6_destination_entry_valid = 0;
+
+            /* Decrease the count of available destinations. */
+            ip_ptr -> nx_ipv6_destination_table_size--;
+        }
+    }
+
+    /* Set a local variable for convenience. */
+    table_size = ip_ptr -> nx_ipv6_destination_table_size;
+
+    /* There is no invalid destination in table. */
+    if (table_size == NX_IPV6_DESTINATION_TABLE_SIZE)
+    {
+        return(NX_NOT_SUCCESSFUL);
+    }
+
+    /* Initialize the pointer to the table location where we will update/add information. */
+    *dest_entry_ptr = NX_NULL;
+
+    /* Go through the table to find an empty slot. */
+    for (i = 0; i < NX_IPV6_DESTINATION_TABLE_SIZE; i++)
+    {
+
+        /* Is this slot empty? */
+        if (!ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid)
+        {
+            /* Yes; we can use it for adding a new entry. */
+            /* Have found an empty slot. */
+            break;
+        }
+    }
+
+    /* Destination is not empty so i must be less than table size. */
+    NX_ASSERT(i < NX_IPV6_DESTINATION_TABLE_SIZE);
+
+    /*
+       If we are here, we did not find a match and are adding a new entry.
+       The process is slightly different from updating a previously existing
+       matching entry, so we handle it separately.
+     */
+
+    /* Clear out any previous data from this slot. */
+    /*lint -e{669} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    memset(&ip_ptr -> nx_ipv6_destination_table[i], 0, sizeof(NX_IPV6_DESTINATION_ENTRY));
+
+    /* Fill in the newly created table entry with the supplied and/or default information. */
+    COPY_IPV6_ADDRESS(destination_address, ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_destination_address);
+
+    /* Add next hop information to the entry. */
+    COPY_IPV6_ADDRESS(next_hop, ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_next_hop);
+
+    /* Attempt to find the matching entry in the cache table. NetX Duo will need to know
+       how to get a packet to the next hop, not just the destination! */
+    status = _nx_nd_cache_find_entry(ip_ptr, next_hop, &ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_nd_entry);
+
+    /* Did not find the matching entry. Try to add one. */
+    if (status)
+    {
+        status = _nx_nd_cache_add_entry(ip_ptr, next_hop, ipv6_address, &ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_nd_entry);
+
+        /* Failed to add new entry. Return. */
+        if (status)
+        {
+            return(NX_NOT_SUCCESSFUL);
+        }
+    }
+
+
+    /* Validate this entry to ensure it will not be overwritten with new entries. */
+    ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid = 1;
+
+    /* Update the count of destinations currently in the table. */
+    ip_ptr -> nx_ipv6_destination_table_size++;
+
+#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
+
+    /* Is a valid path mtu is given? */
+    if (path_mtu > 0)
+    {
+
+        /* Update the destination path MTU with this supplied data. */
+        ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_path_mtu = path_mtu;
+    }
+    else
+    {
+
+        /* No; set the path MTU to the IP task MTU (on link path MTU).*/
+        ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_path_mtu = ipv6_address -> nxd_ipv6_address_attached -> nx_interface_ip_mtu_size;
+    }
+
+    /* Is a valid entry timeout is supplied? */
+    if (mtu_timeout > 0)
+    {
+
+        /* Yes; Update the table entry timeout to the supplied data. */
+        ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_MTU_timer_tick = mtu_timeout;
+    }
+    else
+    {
+
+        /* No; have we defaulted to our own IP task MTU?*/
+        if (ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_path_mtu == ipv6_address -> nxd_ipv6_address_attached -> nx_interface_ip_mtu_size)
+        {
+
+            /* Yes; This is our optimal path MTU. So there is no need to age this table entry
+               and attempt to increase the path MTU; ok set it to infinity. */
+            ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_MTU_timer_tick = NX_WAIT_FOREVER;
+        }
+        else
+        {
+            /* No, this is less than our optimal path MTU. Wait the required interval
+               before probing for a higher path MTU. */
+            ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_MTU_timer_tick = NX_PATH_MTU_INCREASE_WAIT_INTERVAL_TICKS;
+        }
+    }
+#else
+    NX_PARAMETER_NOT_USED(path_mtu);
+    NX_PARAMETER_NOT_USED(mtu_timeout);
+#endif  /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
+
+    /* Set the table location pointer to the entry we just added/updated. */
+    *dest_entry_ptr = &ip_ptr -> nx_ipv6_destination_table[i];
+
+    return(NX_SUCCESS);
+}
+
+#endif  /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_dest_table_find.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_dest_table_find.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_dest_table_find.c	(revision 69)
@@ -0,0 +1,173 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Control Message Protocol (ICMP)                            */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_icmpv6.h"
+
+#ifdef FEATURE_NX_IPV6
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_icmpv6_dest_table_find                          PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function finds a destination table entry based on destination  */
+/*    address.  If no match is found, a the destination entry pointer is  */
+/*    set to NULL, but a successful search status returned.               */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                               Pointer to IP                  */
+/*    destination_address                  Destination IP address.        */
+/*    dest_entry_ptr                       Pointer to location of matching*/
+/*                                             table entry, if any.       */
+/*    path_mtu                             Optional path mtu update.      */
+/*                                           Note: caller shall make sure */
+/*                                           MTU does not exceed physical */
+/*                                           link MTU size.               */
+/*    mtu_timeout                          Optional entry timeout update  */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS                            Search successfully completed */
+/*                                             regardless if match found  */
+/*    NX_NOT_SUCCESSFUL                     Invalid input; search aborted */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    nx_icmpv6_send_queued_packets         Send queued ICMPv6 packets    */
+/*    nx_ipv6_send_packet                   Send specified IPv6 packet    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT _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)
+{
+
+UINT i, table_size;
+
+    /* Destination address must be valid. */
+    NX_ASSERT((destination_address != NX_NULL) && (dest_entry_ptr != NULL));
+
+    /* Set a local variable for convenience. */
+    table_size = ip_ptr -> nx_ipv6_destination_table_size;
+
+    /* Check the destination num. */
+    if (table_size == 0)
+    {
+        return(NX_NOT_SUCCESSFUL);
+    }
+
+    /* Initialize the return value. */
+    *dest_entry_ptr = NX_NULL;
+
+    /* Loop through all entries. */
+    for (i = 0; table_size && (i < NX_IPV6_DESTINATION_TABLE_SIZE); i++)
+    {
+
+        /* Skip invalid entries. */
+        if (!ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid)
+        {
+            continue;
+        }
+
+        /* Keep track of valid entries we have checked. */
+        table_size--;
+
+        /* Check whether or not the address is the same. */
+        if (CHECK_IPV6_ADDRESSES_SAME(&ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_destination_address[0], destination_address))
+        {
+
+#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
+
+            /* Update the table entry if the supplied path MTU is non zero and
+               does not exceed our IP instance MTU. */
+            if (path_mtu > 0)
+            {
+
+                /* Do we have a valid timeout e.g. did this information come from an RA packet?
+                   Or is a packet too big message indicating we need to decrease our path MTU? */
+                if ((mtu_timeout > 0) || (ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_path_mtu > path_mtu))
+                {
+
+                    /* OK to change the path MTU. */
+                    ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_path_mtu = path_mtu;
+
+                    /* Was a valid timeout supplied? */
+                    if (mtu_timeout > 0)
+                    {
+
+                        /* Yes;  Ok to update table entry with the specified timeout. */
+                        ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_MTU_timer_tick = mtu_timeout;
+                    }
+                    else
+                    {
+                        /* No; the path MTU changed in response to a packet too big error
+                           message.  Set the table entry timeout to the required wait
+                           interval.  We cannot attempt to restore (increase) the path MTU
+                           before this time out expires. */
+                        ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_MTU_timer_tick = NX_PATH_MTU_INCREASE_WAIT_INTERVAL_TICKS;
+                    }
+                }
+
+                /* Else this information presumably comes a Packet too Big message.
+                   RFC 1981 disallows increasing a path MTU based on a PTB message
+                   (decreasing is allowed and required). */
+            }
+#else
+            NX_PARAMETER_NOT_USED(path_mtu);
+            NX_PARAMETER_NOT_USED(mtu_timeout);
+#endif /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
+
+            *dest_entry_ptr = &ip_ptr -> nx_ipv6_destination_table[i];
+
+            return(NX_SUCCESS);
+        }
+    }
+
+    return(NX_NOT_SUCCESSFUL);
+}
+
+#endif  /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_perform_DAD.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_perform_DAD.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_perform_DAD.c	(revision 69)
@@ -0,0 +1,170 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Control Message Protocol (ICMP)                            */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_icmpv6.h"
+
+#ifdef NX_IPSEC_ENABLE
+#include "nx_ipsec.h"
+#endif /* NX_IPSEC_ENABLE */
+
+
+#ifdef FEATURE_NX_IPV6
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_icmpv6_perform_DAD                              PORTABLE C      */
+/*                                                           6.1.11       */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function is called from IP thread periodic process routine.    */
+/*    It starts the Duplicate Address Detection process if the interface  */
+/*    address is in tentative state (not validated yet).  It does nothing */
+/*    to an address if the state of the address is not tentative.         */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP instance        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_icmpv6_DAD_clear_NDCache_entry   Remove entry from cache table  */
+/*    _nx_icmpv6_send_ns                   Send a Neighbor Solicitation   */
+/*                                                message                 */
+/*    [ipv6_address_change_notify]         User callback fucntion         */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ip_thraed_entry                                                 */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  04-25-2022     Yuxin Zhou               Modified comment(s), and      */
+/*                                            added internal ip address   */
+/*                                            change notification,        */
+/*                                            resulting in version 6.1.11 */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef NX_DISABLE_IPV6_DAD
+
+VOID _nx_icmpv6_perform_DAD(NX_IP *ip_ptr)
+{
+
+UINT              i;
+NXD_IPV6_ADDRESS *nx_ipv6_address_next;
+
+#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
+UINT              ipv6_addr_index;
+#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
+
+    /* Go through all addresses bound to the IP instance. */
+    for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
+    {
+
+        /* Check if this interface valid. */
+        if (!ip_ptr -> nx_ip_interface[i].nxd_interface_ipv6_address_list_head)
+        {
+            continue;
+        }
+
+        /* Only interested in addresses in the tentative state. */
+        for (nx_ipv6_address_next = ip_ptr -> nx_ip_interface[i].nxd_interface_ipv6_address_list_head;
+             nx_ipv6_address_next;
+             nx_ipv6_address_next = nx_ipv6_address_next -> nxd_ipv6_address_next)
+        {
+
+            /* Check the address state. */
+            if (nx_ipv6_address_next -> nxd_ipv6_address_state == NX_IPV6_ADDR_STATE_TENTATIVE)
+            {
+
+                /* Check if the number of NS messages is used up. */
+                if (nx_ipv6_address_next -> nxd_ipv6_address_DupAddrDetectTransmit)
+                {
+
+                    /* No. This interface is still under DAD.  Transmit a NS */
+                    _nx_icmpv6_send_ns(ip_ptr,
+                                       nx_ipv6_address_next -> nxd_ipv6_address,
+                                       0, nx_ipv6_address_next, 0, NX_NULL);
+
+                    nx_ipv6_address_next -> nxd_ipv6_address_DupAddrDetectTransmit--;
+                }
+                else
+                {
+
+                    /* So far we didn't get any conflict addresses back.
+                       So promote the address to VALID */
+
+                    nx_ipv6_address_next -> nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_VALID;
+                    _nx_icmpv6_DAD_clear_NDCache_entry(ip_ptr,
+                                                       nx_ipv6_address_next -> nxd_ipv6_address);
+
+#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
+                    /* If the callback function is set, invoke the callback function . */
+                    if (ip_ptr -> nx_ipv6_address_change_notify)
+                    {
+                        ipv6_addr_index = (ULONG)nx_ipv6_address_next -> nxd_ipv6_address_index;
+                        ip_ptr -> nx_ipv6_address_change_notify(ip_ptr, NX_IPV6_ADDRESS_DAD_SUCCESSFUL,
+                                                                i, ipv6_addr_index, &nx_ipv6_address_next -> nxd_ipv6_address[0]);
+                    }
+
+                    /* If the internal callback function is set, invoke the callback function . */
+                    if (ip_ptr -> nx_ipv6_address_change_notify_internal)
+                    {
+                        ipv6_addr_index = (ULONG)nx_ipv6_address_next -> nxd_ipv6_address_index;
+                        ip_ptr -> nx_ipv6_address_change_notify_internal(ip_ptr, NX_IPV6_ADDRESS_DAD_SUCCESSFUL,
+                                                                         i, ipv6_addr_index, &nx_ipv6_address_next -> nxd_ipv6_address[0]);
+                    }
+#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
+                }
+            }
+        }
+    }
+}
+
+#endif /* NX_DISABLE_IPV6_DAD */
+
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_send_error_message.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_send_error_message.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_send_error_message.c	(revision 69)
@@ -0,0 +1,379 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Control Message Protocol (ICMPv6)                          */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_packet.h"
+#include "nx_ip.h"
+#include "nx_ipv6.h"
+#include "nx_icmpv6.h"
+
+#ifdef NX_IPSEC_ENABLE
+#include "nx_ipsec.h"
+#endif /* NX_IPSEC_ENABLE */
+
+#ifdef FEATURE_NX_IPV6
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_icmpv6_send_error_message                      PORTABLE C       */
+/*                                                           6.1.10       */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function is called by various IPv6 components to send an       */
+/*    error message when necessary.                                       */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                IP stack instance             */
+/*    offending_packet                      The packet that caused the    */
+/*                                              error.                    */
+/*    word1                                 ICMPv6 error message header   */
+/*                                              field, progarmmed by      */
+/*                                              the caller.               */
+/*    error_pointer                         Pointer to the byte that      */
+/*                                              caused the error          */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ip_checksum_compute               Computer ICMP checksum        */
+/*    _nx_ipv6_packet_send                  Send ICMP packet out          */
+/*    _nx_packet_allocate                   Packet allocate               */
+/*    _nx_packet_release                    Release packet back to pool   */
+/*    _nxd_ipv6_interface_find              Find outgoing interface for   */
+/*                                             sending packet             */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ip_fragment_assembly                                            */
+/*    _nx_ipv6_packet_receive                                             */
+/*    _nx_udp_packet_receive                                              */
+/*    _nx_ipv6_header_option_process                                      */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  01-31-2022     Yuxin Zhou               Modified comment(s),          */
+/*                                            fixed unsigned integers     */
+/*                                            comparison,                 */
+/*                                            resulting in version 6.1.10 */
+/*                                                                        */
+/**************************************************************************/
+VOID _nx_icmpv6_send_error_message(NX_IP *ip_ptr, NX_PACKET *offending_packet,
+                                   ULONG word1, ULONG error_pointer)
+{
+
+NX_PACKET       *pkt_ptr;
+USHORT           checksum;
+#if defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
+UINT             compute_checksum = 1;
+#endif /* defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
+NX_ICMPV6_ERROR *icmpv6_error;
+UINT             bytes_to_copy, i;
+ULONG           *src_ip, *dest_ip;
+ULONG           *src_packet, *dest_packet;
+UINT             payload;
+#ifdef NX_IPSEC_ENABLE
+VOID            *sa = NX_NULL;
+UINT             ret = 0;
+ULONG            data_offset;
+NXD_ADDRESS      src_addr;
+NXD_ADDRESS      dest_addr;
+#endif /* NX_IPSEC_ENABLE */
+
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, offending_packet);
+
+    /* Do not send ICMPv6 error message if ICMPv6 is not enabled. */
+    if (ip_ptr -> nx_ip_icmpv6_packet_process == NX_NULL)
+    {
+        return;
+    }
+
+    /* Find out the source and destination IP addresses of the offending packet. */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    src_ip = (((NX_IPV6_HEADER *)(offending_packet -> nx_packet_ip_header)) -> nx_ip_header_source_ip);
+
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    dest_ip = (((NX_IPV6_HEADER *)(offending_packet -> nx_packet_ip_header)) -> nx_ip_header_destination_ip);
+
+    if (CHECK_UNSPECIFIED_ADDRESS(src_ip))
+    {
+        /*
+         * Sender of the offending packet is unspecified.
+         * So we shouldn't send out ICMP error message.
+         * Drop the packet and return.
+         */
+        return;
+    }
+
+    /* Allocate a packet to build the ICMPv6 error message in.  */
+    if (_nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &pkt_ptr, NX_IPv6_ICMP_PACKET, NX_NO_WAIT))
+    {
+
+        /* Error getting packet, so just get out!  */
+        return;
+    }
+
+    /* Check to see if the packet has enough room to fill with the ICMPv6 error header.  */
+    if ((UINT)(pkt_ptr -> nx_packet_data_end - pkt_ptr -> nx_packet_prepend_ptr) < sizeof(NX_ICMPV6_ERROR))
+    {
+
+        /* Error getting packet, so just get out!  */
+        _nx_packet_release(pkt_ptr);
+        return;
+    }
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, pkt_ptr);
+
+    /* Mark the packet as IPv6. */
+    /*lint -e{644} suppress variable might not be initialized, since "pkt_ptr" was initialized in _nx_packet_allocate. */
+    pkt_ptr -> nx_packet_ip_version = NX_IP_VERSION_V6;
+
+    /* Setup the size of the ICMPv6 NA message */
+
+    /* Size of the message is ICMPv6 */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    icmpv6_error = (NX_ICMPV6_ERROR *)(pkt_ptr -> nx_packet_prepend_ptr);
+    icmpv6_error -> nx_icmpv6_error_header.nx_icmpv6_header_type = (UCHAR)((word1 >> 24) & 0xFF);
+    icmpv6_error -> nx_icmpv6_error_header.nx_icmpv6_header_code = (UCHAR)((word1 >> 16) & 0xFF);
+    icmpv6_error -> nx_icmpv6_error_header.nx_icmpv6_header_checksum = 0;
+
+    icmpv6_error -> nx_icmpv6_error_pointer = error_pointer;
+
+    /* Change to network byte order. */
+    NX_CHANGE_ULONG_ENDIAN(icmpv6_error -> nx_icmpv6_error_pointer);
+
+    /* Figure out how many bytes we should copy from the offending packet not including ethernet
+       frame header. */
+    /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+    bytes_to_copy = (UINT)(offending_packet -> nx_packet_append_ptr - offending_packet -> nx_packet_ip_header);
+
+    /* Check that the number of bytes to copy does not exceed the minimum size ICMPv6 message
+       as per RFC 2460. */
+    if ((bytes_to_copy + sizeof(NX_ICMPV6_ERROR) + sizeof(NX_IPV6_HEADER)) >= NX_MINIMUM_IPV6_PATH_MTU)
+    {
+
+        /* Subtract size of IPv6 and ICMPv6 headers from the ICMPv6 error message packet. */
+        bytes_to_copy = (UINT)(NX_MINIMUM_IPV6_PATH_MTU - (sizeof(NX_IPV6_HEADER) + sizeof(NX_ICMPV6_ERROR)));
+    }
+
+    /* Check how much of the offending packet data will fit in the allocated packet, leaving
+       room for the Physical frame header, IPv6 header and ICMPv6 header of the error message. */
+    payload = pkt_ptr -> nx_packet_pool_owner -> nx_packet_pool_payload_size;
+
+    if (((INT)((bytes_to_copy + sizeof(NX_IPV6_HEADER) + sizeof(NX_ICMPV6_ERROR) + NX_PHYSICAL_HEADER) - payload)) > 0)
+    {
+
+        bytes_to_copy = (UINT)(payload - (sizeof(NX_IPV6_HEADER) + sizeof(NX_ICMPV6_ERROR) + NX_PHYSICAL_HEADER));
+    }
+
+    /* Set the packet length and pointers.  The length will be increased to include
+       the IPv6 header in the IP send function.  The Prepend function will be similarly
+       updated in the IP send function. */
+    pkt_ptr -> nx_packet_length = bytes_to_copy + (ULONG)sizeof(NX_ICMPV6_ERROR);
+    pkt_ptr -> nx_packet_append_ptr = pkt_ptr -> nx_packet_prepend_ptr + pkt_ptr -> nx_packet_length;
+
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    src_packet  = (ULONG *)(offending_packet -> nx_packet_ip_header);
+
+    /*lint -e{923} suppress cast between pointer and ULONG, since it is necessary  */
+    dest_packet = (ULONG *)NX_UCHAR_POINTER_ADD(icmpv6_error, sizeof(NX_ICMPV6_ERROR));
+
+    /* Endian swap the incoming IPv6 header (10 ULONGs = 40 bytes)
+       to network byte order. */
+    for (i = 0; i < 10; i++)
+    {
+        NX_CHANGE_ULONG_ENDIAN(*src_packet);
+        src_packet++;
+    }
+
+    /* Reset the packet pointer to the received packet IP header. */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    src_packet  = (ULONG *)(offending_packet -> nx_packet_ip_header);
+
+    /* Copy the data from the received packet to the ICMPv6 error packet. */
+    for (; (INT)bytes_to_copy > 0; bytes_to_copy -= 4)
+    {
+
+        *dest_packet++ = *src_packet++;
+    }
+
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    src_packet  = (ULONG *)(offending_packet -> nx_packet_ip_header);
+
+    /* Endian swap the IPv6 header back to host byte order. */
+    for (i = 0; i < 10; i++)
+    {
+        NX_CHANGE_ULONG_ENDIAN(*src_packet);
+        src_packet++;
+    }
+
+    /* If we received the packet through a Multicast address, we pick an outgoing address
+       based on multicast scope (RFC 3484, 3.1) */
+    if (IPv6_Address_Type(dest_ip) & IPV6_ADDRESS_MULTICAST)
+    {
+
+        if (_nxd_ipv6_interface_find(ip_ptr, dest_ip,
+                                     &pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr,
+                                     NX_NULL))
+        {
+
+            /* Cannot find usable outgoing interface. */
+            _nx_packet_release(pkt_ptr);
+            return;
+        }
+    }
+    else
+    {
+
+        /* If this ICMPv6 error message is a response to a packet sent to link local or global address,
+           use the corresponding interface address as sender's address. */
+        pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr = offending_packet -> nx_packet_address.nx_packet_ipv6_address_ptr;
+    }
+
+    /*
+       Check if a suitable outoing address was found, and the
+       outgoing address is not valid:
+     */
+    if ((pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr == NX_NULL) ||
+        (pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_VALID))
+    {
+
+        /* No good. Drop the packet and return. */
+        _nx_packet_release(pkt_ptr);
+        return;
+    }
+
+#ifdef NX_IPSEC_ENABLE
+
+    /* Check for possible SA match. */
+    if (ip_ptr -> nx_ip_packet_egress_sa_lookup != NX_NULL)               /* IPsec is enabled. */
+    {
+
+        /* Set up IP address. */
+        src_addr.nxd_ip_version = NX_IP_VERSION_V6;
+
+        COPY_IPV6_ADDRESS(pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address,
+                          src_addr.nxd_ip_address.v6);
+
+        dest_addr.nxd_ip_version = NX_IP_VERSION_V6;
+
+        COPY_IPV6_ADDRESS(src_ip, dest_addr.nxd_ip_address.v6);
+
+        /* If the SA has not been set. */
+        ret = ip_ptr -> nx_ip_packet_egress_sa_lookup(ip_ptr,                 /* IP ptr */
+                                                      &src_addr,              /* src_addr */
+                                                      &dest_addr,             /* dest_addr */
+                                                      NX_PROTOCOL_ICMPV6,     /* protocol */
+                                                      0,                      /* src_port */
+                                                      0,                      /* dest_port */
+                                                      &data_offset, &sa,
+                                                      ((word1 >> 16) & 0xFFFF));
+        if (ret == NX_IPSEC_TRAFFIC_BYPASS)
+        {
+            sa = NX_NULL;
+            data_offset = 0;
+        }
+        else if (ret == NX_IPSEC_TRAFFIC_DROP || ret == NX_IPSEC_TRAFFIC_PENDING_IKEV2)
+        {
+
+            /* IPSec SA disallows this packet. Drop the packet and return. */
+            _nx_packet_release(pkt_ptr);
+
+            return;
+        }
+    }
+
+    pkt_ptr -> nx_packet_ipsec_sa_ptr = sa;
+
+#endif /* NX_IPSEC_ENABLE */
+
+#ifdef NX_DISABLE_ICMPV6_TX_CHECKSUM
+    compute_checksum = 0;
+#endif /* NX_DISABLE_ICMPV6_TX_CHECKSUM */
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    if (pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM)
+    {
+        compute_checksum = 0;
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+#ifdef NX_IPSEC_ENABLE
+    if ((sa != NX_NULL) && (((NX_IPSEC_SA *)sa) -> nx_ipsec_sa_encryption_method != NX_CRYPTO_NONE))
+    {
+        compute_checksum = 1;
+    }
+#endif /* NX_IPSEC_ENABLE */
+#if defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
+    if (compute_checksum)
+#endif /* defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
+    {
+        /* Compute the check sum */
+        checksum = _nx_ip_checksum_compute(pkt_ptr, NX_PROTOCOL_ICMPV6,
+                                           (UINT)pkt_ptr -> nx_packet_length,
+                                           pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address,
+                                           src_ip);
+
+        icmpv6_error -> nx_icmpv6_error_header.nx_icmpv6_header_checksum = (USHORT)(~checksum);
+
+        /* Swap to network byte order. */
+        NX_CHANGE_USHORT_ENDIAN(icmpv6_error -> nx_icmpv6_error_header.nx_icmpv6_header_checksum);
+    }
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    else
+    {
+        pkt_ptr -> nx_packet_interface_capability_flag |= NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM;
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+    /* Transmit the packet.  The hop limit is set to 255. */
+    _nx_ipv6_packet_send(ip_ptr, pkt_ptr, NX_PROTOCOL_ICMPV6, pkt_ptr -> nx_packet_length, 255,
+                         pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address,
+                         src_ip);
+
+    return;
+}
+#endif /* NX_DISABLE_ICMPV6_ERROR_MESSAGE */
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_send_ns.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_send_ns.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_send_ns.c	(revision 69)
@@ -0,0 +1,321 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Control Message Protocol (ICMP)                            */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_packet.h"
+#include "nx_ip.h"
+#include "nx_ipv6.h"
+#include "nx_icmpv6.h"
+
+
+#ifdef FEATURE_NX_IPV6
+static const ULONG _nx_ipv6_unspecified_address[4] = {0, 0, 0, 0};
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_icmpv6_send_ns                                  PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*   This function sends out an ICMPv6 Neighbor Solicitation (NS) message.*/
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    targetIPAddr                          Target IPv6 Address           */
+/*    send_slla                             Send Source Link Layer Address*/
+/*    outgoing_address                      IP interface to transmit the  */
+/*                                                 packet out on          */
+/*    sendUnicast                           Send out a unicast NS         */
+/*    NDCacheEntry                          Pointer to ND cache entry     */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ip_checksum_compute               Computer ICMP checksum        */
+/*    _nx_ipv6_packet_send                  Send packet out               */
+/*    _nx_packet_allocate                   Packet allocate function      */
+/*    _nx_packet_release                    Packet release function       */
+/*    _nx_ipv6_header_add                   Add IPv6 header               */
+/*    (ip_link_driver)                      User supplied link driver     */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_icmpv6_packet_process             Main ICMP packet pocess       */
+/*    _nx_icmpv6_perform_DAD                Procedure for Duplicate       */
+/*                                             Address Detection.         */
+/*    _nx_ipv6_packet_send                  IPv6 packet transmit process  */
+/*    _nx_nd_cache_periodic_update          ND Cache timeout routine.     */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID _nx_icmpv6_send_ns(NX_IP                 *ip_ptr,
+                        ULONG                 *neighbor_IP_address,
+                        INT                    send_slla,
+                        NXD_IPV6_ADDRESS      *outgoing_address,
+                        INT                    sendUnicast,
+                        ND_CACHE_ENTRY        *NDCacheEntry)
+{
+
+NX_PACKET    *pkt_ptr;
+USHORT        checksum;
+#if defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
+UINT          compute_checksum = 1;
+#endif /* defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
+NX_ICMPV6_ND *nd_ptr;
+ULONG        *src_address;
+ULONG         dest_address[4];
+NX_IP_DRIVER  driver_request;
+
+
+    /* Allocate a packet to build the ICMPv6 NS message in.  */
+#ifdef NX_ENABLE_DUAL_PACKET_POOL
+    /* Allocate from auxiliary packet pool first. */
+    if (_nx_packet_allocate(ip_ptr -> nx_ip_auxiliary_packet_pool, &pkt_ptr, NX_IPv6_ICMP_PACKET, NX_NO_WAIT))
+    {
+        if (ip_ptr -> nx_ip_auxiliary_packet_pool != ip_ptr -> nx_ip_default_packet_pool)
+#endif /* NX_ENABLE_DUAL_PACKET_POOL */
+        {
+            if (_nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool, &pkt_ptr, NX_IPv6_ICMP_PACKET, NX_NO_WAIT))
+            {
+
+                /* Error getting packet, so just get out!  */
+                return;
+            }
+        }
+#ifdef NX_ENABLE_DUAL_PACKET_POOL
+        else
+        {
+
+            /* Error getting packet, so just get out!  */
+            return;
+        }
+    }
+#endif /* NX_ENABLE_DUAL_PACKET_POOL */
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, pkt_ptr);
+
+    /* Mark the packet as IPv6 packet. */
+    /*lint -e{644} suppress variable might not be initialized, since "pkt_ptr" was initialized in _nx_packet_allocate. */
+    pkt_ptr -> nx_packet_ip_version = NX_IP_VERSION_V6;
+
+    /* Setup the size of the ICMPv6 NS message */
+    pkt_ptr -> nx_packet_length = sizeof(NX_ICMPV6_ND);
+
+    /* Add 8 more bytes if sending source link layer address. */
+    if (send_slla)
+    {
+        pkt_ptr -> nx_packet_length += 8;
+    }
+
+    /* Check to see if the packet has enough room to fill with NS.  */
+    if ((UINT)(pkt_ptr -> nx_packet_data_end - pkt_ptr -> nx_packet_prepend_ptr) < pkt_ptr -> nx_packet_length)
+    {
+
+        /* Error getting packet, so just get out!  */
+        _nx_packet_release(pkt_ptr);
+        return;
+    }
+
+    /* Setup the append pointer to the end of the message. */
+    pkt_ptr -> nx_packet_append_ptr = pkt_ptr -> nx_packet_prepend_ptr + pkt_ptr -> nx_packet_length;
+
+    /* Set up the ND message in the buffer. */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    nd_ptr = (NX_ICMPV6_ND *)(pkt_ptr -> nx_packet_prepend_ptr);
+    nd_ptr -> nx_icmpv6_nd_header.nx_icmpv6_header_type = NX_ICMPV6_NEIGHBOR_SOLICITATION_TYPE;
+    nd_ptr -> nx_icmpv6_nd_header.nx_icmpv6_header_code = 0;
+    nd_ptr -> nx_icmpv6_nd_header.nx_icmpv6_header_checksum = 0;
+    nd_ptr -> nx_icmpv6_nd_flag = 0;
+
+    /* copy the target IP address */
+    COPY_IPV6_ADDRESS(neighbor_IP_address, nd_ptr -> nx_icmpv6_nd_targetAddress);
+
+    /* Convert the IP address to network byte order. */
+    NX_IPV6_ADDRESS_CHANGE_ENDIAN(nd_ptr -> nx_icmpv6_nd_targetAddress);
+
+    if (sendUnicast)
+    {
+
+        COPY_IPV6_ADDRESS(neighbor_IP_address, dest_address);
+    }
+    else
+    {
+
+        /* Set up the next hop address, which is the target host's Solicited-Node
+           Multicast Address.  The address is formed by taking the last 24 bits of
+           the target IP address, in the form of:
+           0xFF02:0000:0000:0000:0000:0001:FFxx:xxxx */
+        SET_SOLICITED_NODE_MULTICAST_ADDRESS(dest_address, neighbor_IP_address);
+    }
+
+    /* Set up source IP address to use for this packet.
+       If the global address is not valid yet, we use the unspecified address (::)
+       Otherwise the global address is used */
+    if (outgoing_address -> nxd_ipv6_address_state == NX_IPV6_ADDR_STATE_VALID)
+    {
+
+        src_address = outgoing_address -> nxd_ipv6_address;
+    }
+    else
+    {
+
+        /*lint -e{929} suppress cast of pointer to pointer, since it is necessary  */
+        src_address = (ULONG *)_nx_ipv6_unspecified_address;
+    }
+
+    pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr = outgoing_address;
+
+    /* outgoing_address -> nxd_ipv6_address_attached can not be NULL. */
+    NX_ASSERT(outgoing_address -> nxd_ipv6_address_attached != NX_NULL);
+
+    if (send_slla)  /* Need to send SLLA option */
+    {
+
+    USHORT           *mac_addr;
+    NX_ICMPV6_OPTION *nd_options;
+
+        /*lint -e{923} suppress cast between pointer and ULONG, since it is necessary  */
+        nd_options = (NX_ICMPV6_OPTION *)NX_UCHAR_POINTER_ADD(nd_ptr, sizeof(NX_ICMPV6_ND));
+
+        /* Fill in the options field */
+        nd_options -> nx_icmpv6_option_type = 1;
+        nd_options -> nx_icmpv6_option_length = 1;
+
+        /* Fill in the source MAC address */
+        mac_addr = &nd_options ->  nx_icmpv6_option_data;
+        mac_addr[0] = (USHORT)(outgoing_address -> nxd_ipv6_address_attached -> nx_interface_physical_address_msw);
+        mac_addr[1] = (USHORT)((outgoing_address -> nxd_ipv6_address_attached -> nx_interface_physical_address_lsw & 0xFFFF0000) >> 16); /* lgtm[cpp/overflow-buffer] */
+        mac_addr[2] = (USHORT)(outgoing_address -> nxd_ipv6_address_attached -> nx_interface_physical_address_lsw & 0x0000FFFF); /* lgtm[cpp/overflow-buffer] */
+
+        /* Byte swapping. */
+        NX_CHANGE_USHORT_ENDIAN(mac_addr[0]);
+        NX_CHANGE_USHORT_ENDIAN(mac_addr[1]); /* lgtm[cpp/overflow-buffer] */
+        NX_CHANGE_USHORT_ENDIAN(mac_addr[2]); /* lgtm[cpp/overflow-buffer] */
+    }
+
+#ifdef NX_DISABLE_ICMPV6_TX_CHECKSUM
+    compute_checksum = 0;
+#endif /* NX_DISABLE_ICMPV6_TX_CHECKSUM */
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    if (outgoing_address -> nxd_ipv6_address_attached -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM)
+    {
+        compute_checksum = 0;
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+#if defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
+    if (compute_checksum)
+#endif /* defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
+    {
+        /* Compute checksum.  The return value is already in network byte order */
+        checksum = _nx_ip_checksum_compute(pkt_ptr, NX_PROTOCOL_ICMPV6, (UINT)pkt_ptr -> nx_packet_length, src_address, dest_address);
+
+        checksum = (USHORT)(~checksum);
+
+        /* Byte swapping. */
+        NX_CHANGE_USHORT_ENDIAN(checksum);
+
+        nd_ptr -> nx_icmpv6_nd_header.nx_icmpv6_header_checksum = checksum;
+    }
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    else
+    {
+        pkt_ptr -> nx_packet_interface_capability_flag |= NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM;
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+    /* Add IPv6 header. */
+    if (_nx_ipv6_header_add(ip_ptr, &pkt_ptr, NX_PROTOCOL_ICMPV6, pkt_ptr -> nx_packet_length,
+                            255, src_address, dest_address, NX_NULL) != NX_SUCCESS)
+    {
+
+        /* Failed to add header. */
+        return;
+    }
+
+    /* Build the driver request. */
+    driver_request.nx_ip_driver_ptr                  = ip_ptr;
+    driver_request.nx_ip_driver_command              = NX_LINK_PACKET_SEND;
+    driver_request.nx_ip_driver_packet               = pkt_ptr;
+    driver_request.nx_ip_driver_interface            = outgoing_address -> nxd_ipv6_address_attached;
+    if (sendUnicast)
+    {
+    UCHAR *mac_addr;
+        mac_addr = NDCacheEntry -> nx_nd_cache_mac_addr;
+
+        /* Set unicast destination MAC. */
+        driver_request.nx_ip_driver_physical_address_msw = ((ULONG)mac_addr[0] << 8) | mac_addr[1];
+        driver_request.nx_ip_driver_physical_address_lsw =
+            ((ULONG)mac_addr[2] << 24) | ((ULONG)mac_addr[3] << 16) | ((ULONG)mac_addr[4] << 8) | mac_addr[5];
+    }
+    else
+    {
+
+        /*lint -e{644} suppress variable might not be initialized, since dest_address was initialized. */
+        driver_request.nx_ip_driver_physical_address_msw = 0x00003333;
+        driver_request.nx_ip_driver_physical_address_lsw = dest_address[3];
+    }
+
+#ifndef NX_DISABLE_IP_INFO
+
+    /* Increment the IP packet sent count.  */
+    ip_ptr -> nx_ip_total_packets_sent++;
+
+    /* Increment the IP bytes sent count.  */
+    ip_ptr -> nx_ip_total_bytes_sent +=  pkt_ptr -> nx_packet_length - (ULONG)sizeof(NX_IPV6_HEADER);
+#endif
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, pkt_ptr);
+
+    /* Driver entry must not be NULL. */
+    NX_ASSERT(outgoing_address -> nxd_ipv6_address_attached -> nx_interface_link_driver_entry != NX_NULL);
+
+    /* Send the IP packet out on the network via the attached driver.  */
+    (outgoing_address -> nxd_ipv6_address_attached -> nx_interface_link_driver_entry)(&driver_request);
+}
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_send_rs.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_send_rs.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_icmpv6_send_rs.c	(revision 69)
@@ -0,0 +1,221 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Control Message Protocol (ICMP)                            */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+#include "nx_api.h"
+#include "nx_packet.h"
+#include "nx_ip.h"
+#include "nx_ipv6.h"
+#include "nx_icmpv6.h"
+
+#ifdef FEATURE_NX_IPV6
+#ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
+static const ULONG _nx_ipv6_all_router_address[4] = {0xff020000, 0, 0, 2};
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_icmpv6_send_rs                                  PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function sends an ICMPv6 Router Solicitation message.          */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    if_index                              Index of interface            */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS: RS packet is sent                                       */
+/*    NX_NOT_SUCCESSFUL: RS packet is not sent                            */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ip_checksum_compute               Computer ICMP checksum        */
+/*    _nx_ipv6_packet_send                  Send ICMPv6 packet out        */
+/*    _nx_packet_allocate                   Packet allocation function    */
+/*    _nxd_ipv6_interface_find              Find outgoing interface for   */
+/*                                             sending packet             */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nxd_ipv6_router_solicitation_check   IPv6 router solicitation      */
+/*                                             timeout routine.           */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nx_icmpv6_send_rs(NX_IP *ip_ptr, UINT if_index)
+{
+
+USHORT           *mac_addr;
+NX_PACKET        *pkt_ptr;
+USHORT            checksum;
+#if defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
+UINT              compute_checksum = 1;
+#endif /* defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
+NX_ICMPV6_RS     *rs_ptr;
+NX_ICMPV6_OPTION *rs_options;
+
+
+    /* Do not send RS packet if ICMPv6 is not enabled. */
+    if (ip_ptr -> nx_ip_icmpv6_packet_process == NX_NULL)
+    {
+        return(NX_NOT_SUCCESSFUL);
+    }
+
+    /* Allocate a packet to build the ICMPv6 router
+       solicitation message in.  */
+#ifdef NX_ENABLE_DUAL_PACKET_POOL
+    /* Allocate from auxiliary packet pool first. */
+    if (_nx_packet_allocate(ip_ptr -> nx_ip_auxiliary_packet_pool, &pkt_ptr, (NX_ICMP_PACKET + sizeof(NX_ICMPV6_RS) + 8), NX_NO_WAIT))
+    {
+        if (ip_ptr -> nx_ip_auxiliary_packet_pool != ip_ptr -> nx_ip_default_packet_pool)
+#endif /* NX_ENABLE_DUAL_PACKET_POOL */
+        {
+            if (_nx_packet_allocate(ip_ptr -> nx_ip_default_packet_pool,
+                                    &pkt_ptr, (NX_ICMP_PACKET + sizeof(NX_ICMPV6_RS) + 8), NX_NO_WAIT))
+            {
+
+                /* Error getting packet, so just get out!  */
+                return(NX_NOT_SUCCESSFUL);
+            }
+        }
+#ifdef NX_ENABLE_DUAL_PACKET_POOL
+        else
+        {
+
+            /* Error getting packet, so just get out!  */
+            return(NX_NOT_SUCCESSFUL);
+        }
+    }
+#endif /* NX_ENABLE_DUAL_PACKET_POOL */
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, pkt_ptr);
+
+    /* Find a valid IPv6 address. */
+    if (_nxd_ipv6_interface_find(ip_ptr, (ULONG *)_nx_ipv6_all_router_address,
+                                 &pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr,
+                                 &ip_ptr -> nx_ip_interface[if_index]))
+    {
+        _nx_packet_release(pkt_ptr);
+        return(NX_NOT_SUCCESSFUL);
+    }
+
+    /*lint -e{644} suppress variable might not be initialized, since "pkt_ptr" was initialized in _nx_packet_allocate. */
+    pkt_ptr -> nx_packet_ip_version = NX_IP_VERSION_V6;
+
+    /* Set the size of the ICMPv6 router solicitation message. */
+    /* Size of the message is ICMPv6 + options, which is 8 bytes. */
+    pkt_ptr -> nx_packet_length = (sizeof(NX_ICMPV6_RS) + 8);
+
+    /* Set the prepend pointer. */
+    pkt_ptr -> nx_packet_prepend_ptr -= pkt_ptr -> nx_packet_length;
+
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    rs_ptr = (NX_ICMPV6_RS *)(pkt_ptr -> nx_packet_prepend_ptr);
+    rs_ptr -> nx_icmpv6_rs_icmpv6_header.nx_icmpv6_header_type = NX_ICMPV6_ROUTER_SOLICITATION_TYPE;
+    rs_ptr -> nx_icmpv6_rs_icmpv6_header.nx_icmpv6_header_code = 0;
+    rs_ptr -> nx_icmpv6_rs_icmpv6_header.nx_icmpv6_header_checksum = 0;
+    rs_ptr -> nx_icmpv6_rs_reserved = 0;
+
+    /* Get a pointer to the Option header in the ICMPv6 header. */
+    /*lint -e{923} suppress cast between pointer and ULONG, since it is necessary  */
+    rs_options = (NX_ICMPV6_OPTION *)NX_UCHAR_POINTER_ADD(rs_ptr, sizeof(NX_ICMPV6_RS));
+
+    /* Fill in the options field */
+    rs_options -> nx_icmpv6_option_type = ICMPV6_OPTION_TYPE_SRC_LINK_ADDR;
+    rs_options -> nx_icmpv6_option_length = 1;
+
+    /* Fill in the source mac address. */
+    mac_addr = &rs_options -> nx_icmpv6_option_data;
+    mac_addr[0] = (USHORT)(ip_ptr -> nx_ip_interface[if_index].nx_interface_physical_address_msw);
+    mac_addr[1] = (USHORT)((ip_ptr -> nx_ip_interface[if_index].nx_interface_physical_address_lsw & 0xFFFF0000) >> 16); /* lgtm[cpp/overflow-buffer] */
+    mac_addr[2] = (USHORT)(ip_ptr -> nx_ip_interface[if_index].nx_interface_physical_address_lsw & 0x0000FFFF); /* lgtm[cpp/overflow-buffer] */
+
+    /* Byte swapping. */
+    NX_CHANGE_USHORT_ENDIAN(mac_addr[0]);
+    NX_CHANGE_USHORT_ENDIAN(mac_addr[1]); /* lgtm[cpp/overflow-buffer] */
+    NX_CHANGE_USHORT_ENDIAN(mac_addr[2]); /* lgtm[cpp/overflow-buffer] */
+
+#ifdef NX_DISABLE_ICMPV6_TX_CHECKSUM
+    compute_checksum = 0;
+#endif /* NX_DISABLE_ICMPV6_TX_CHECKSUM */
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    if (ip_ptr -> nx_ip_interface[if_index].nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM)
+    {
+        compute_checksum = 0;
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+#if defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
+    if (compute_checksum)
+#endif /* defined(NX_DISABLE_ICMPV6_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
+    {
+
+        /* Compute checksum.  The returned value is already in network byte order. */
+        /*lint -e{929} suppress cast of pointer to pointer, since it is necessary  */
+        checksum = _nx_ip_checksum_compute(pkt_ptr, NX_PROTOCOL_ICMPV6,
+                                           (UINT)pkt_ptr -> nx_packet_length,
+                                           pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address,
+                                           (ULONG *)_nx_ipv6_all_router_address);
+
+        checksum = (USHORT)(~checksum);
+
+        /* Byte swapping. */
+        NX_CHANGE_USHORT_ENDIAN(checksum);
+
+        rs_ptr -> nx_icmpv6_rs_icmpv6_header.nx_icmpv6_header_checksum = checksum;
+    }
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    else
+    {
+        pkt_ptr -> nx_packet_interface_capability_flag |= NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM;
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+    /*lint -e{929} suppress cast of pointer to pointer, since it is necessary  */
+    _nx_ipv6_packet_send(ip_ptr, pkt_ptr, NX_PROTOCOL_ICMPV6, pkt_ptr -> nx_packet_length, 255,
+                         pkt_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address,
+                         (ULONG *)_nx_ipv6_all_router_address);
+
+    return(NX_SUCCESS);
+}
+#endif /* NX_DISABLE_ICMPV6_ROUTER_SOLICITATION */
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_igmp_multicast_check.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_igmp_multicast_check.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_igmp_multicast_check.c	(revision 69)
@@ -0,0 +1,108 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Group Management Protocol (IGMP)                           */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_igmp.h"
+
+
+#ifndef NX_DISABLE_IPV4
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_igmp_multicast_check                            PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function checks the list of joined multicast addresses to see  */
+/*    if the incoming address matches.  If the specified group is         */
+/*    "all hosts" or if a match is found, NX_TRUE is returned to the      */
+/*    caller.                                                             */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                IP instance pointer           */
+/*    group                                 Multicast group IP address    */
+/*    nx_interface                          Pointer to interface          */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_TRUE                               If a match is found           */
+/*    NX_FALSE                              Otherwise                     */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ipv4_packet_receive               Raw IP packet receive         */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nx_igmp_multicast_check(NX_IP *ip_ptr, ULONG group, NX_INTERFACE *nx_interface)
+{
+
+UINT i;
+
+    /* Check for "all hosts" group.  We always assume all hosts membership.  */
+    /*lint -e{835} -e{845} suppress operating on zero. */
+    if (group ==  NX_ALL_HOSTS_ADDRESS)
+    {
+        return(NX_TRUE);
+    }
+
+    /* Loop through the IP multicast join list to find the matching group that is being
+       responded to by another host on this same network.  */
+
+    for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++)
+    {
+
+        /* Check for a match.  */
+        if ((ip_ptr -> nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_list == group) &&
+            (nx_interface == ip_ptr -> nx_ipv4_multicast_entry[i].nx_ipv4_multicast_join_interface_list))
+        {
+            return(NX_TRUE);
+        }
+    }
+
+    /* Otherwise, we have searched the entire list, return false.  */
+    return(NX_FALSE);
+}
+#endif /* !NX_DISABLE_IPV4  */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_invalidate_destination_entry.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_invalidate_destination_entry.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_invalidate_destination_entry.c	(revision 69)
@@ -0,0 +1,116 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Control Message Protocol (ICMP)                            */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_icmpv6.h"
+
+#ifdef FEATURE_NX_IPV6
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_invalidate_destination_entry                    PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function invalidates all destination entries whose next hop    */
+/*    address matches the supplied IP address regardless of the           */
+/*    destination address.                                                */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP                 */
+/*    next_hop_ip                           The next hop address to find  */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nd_cache_delete                      Delete a neighbor cache.      */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID _nx_invalidate_destination_entry(NX_IP *ip_ptr, ULONG *next_hop_ip)
+{
+
+UINT i, table_size;
+
+    /* Set a local variable for convenience. */
+    table_size = ip_ptr -> nx_ipv6_destination_table_size;
+
+    /* Check if there have been any destinations in the table. */
+    if (table_size == 0)
+    {
+        return;
+    }
+
+    /* Loop through the whole table to match the IP address. */
+    for (i = 0; table_size && (i < NX_IPV6_DESTINATION_TABLE_SIZE); i++)
+    {
+
+        /* Skip over empty slots. */
+        if (!ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid)
+        {
+            continue;
+        }
+
+        /* Keep track of valid entries we have checked. */
+        table_size--;
+
+        /* Match the supplied next hop with the table entry next hop. */
+        if (CHECK_IPV6_ADDRESSES_SAME(ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_next_hop, next_hop_ip))
+        {
+
+            /* A matching entry is found.  Mark the entry as invalid. */
+            ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid = 0;
+
+            /* Decrease the count of available destinations. */
+            ip_ptr -> nx_ipv6_destination_table_size--;
+        }
+    }
+
+    return;
+}
+
+#endif  /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_checksum_compute.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_checksum_compute.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_checksum_compute.c	(revision 69)
@@ -0,0 +1,281 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol Checksum Computation                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_icmp.h"
+#include "nx_icmpv6.h"
+#include "nx_ip.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_checksum_compute                           PORTABLE C        */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function computes the checksum from the supplied packet        */
+/*    pointer and IP address fields required for the pseudo header.       */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    packet_ptr                            Pointer to packet             */
+/*    protocol                              Protocol type                 */
+/*    data_length                           Size of the protocol payload  */
+/*    src_ip_addr                           IPv4 or IPv6 address, used in */
+/*                                             constructing pseudo header.*/
+/*    dest_ip_addr                          IPv4 or IPv6 address, used in */
+/*                                             constructing pseudo header.*/
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    computed checksum                                                   */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Duo internal routines                                          */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+USHORT  _nx_ip_checksum_compute(NX_PACKET *packet_ptr, ULONG protocol,
+                                UINT data_length, ULONG *src_ip_addr,
+                                ULONG *dest_ip_addr)
+{
+
+ULONG      checksum = 0;
+USHORT     tmp;
+USHORT    *short_ptr;
+ULONG     *long_ptr;
+#ifndef NX_DISABLE_PACKET_CHAIN
+ULONG      packet_size;
+#endif /* NX_DISABLE_PACKET_CHAIN */
+NX_PACKET *current_packet;
+ALIGN_TYPE end_ptr;
+#ifdef FEATURE_NX_IPV6
+UINT       i;
+#endif
+
+    /* For computing TCP/UDP/ICMPv6, we need to include the pseudo header.
+       The ICMPv4 checksum does not cover the pseudo header. */
+    if ((protocol == NX_PROTOCOL_UDP) ||
+#ifdef FEATURE_NX_IPV6
+        (protocol == NX_PROTOCOL_ICMPV6) ||
+#endif /* FEATURE_NX_IPV6 */
+        (protocol == NX_PROTOCOL_TCP))
+    {
+
+    USHORT *src_ip_short, *dest_ip_short;
+
+        checksum = protocol;
+
+        /* The addresses must not be null.  */
+        NX_ASSERT((src_ip_addr != NX_NULL) && (dest_ip_addr != NX_NULL));
+
+        /*lint -e{929} -e{740} suppress cast of pointer to pointer, since it is necessary  */
+        src_ip_short = (USHORT *)src_ip_addr;
+
+        /*lint -e{929} -e{740} suppress cast of pointer to pointer, since it is necessary  */
+        dest_ip_short = (USHORT *)dest_ip_addr;
+
+
+        checksum += src_ip_short[0];
+        checksum += src_ip_short[1];
+        checksum += dest_ip_short[0];
+        checksum += dest_ip_short[1];
+
+#ifdef FEATURE_NX_IPV6
+
+        /* Note that the IPv6 address is 128 bits/4 words
+           compared with the 32 IPv4 address.*/
+        if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6)
+        {
+
+            for (i = 2; i < 8; i++)
+            {
+
+                checksum += dest_ip_short[i];
+                checksum += src_ip_short[i];
+            }
+        }
+#endif /* FEATURE_NX_IPV6 */
+
+        /* Take care of data length */
+        checksum += data_length;
+
+        /* Fold a 4-byte value into a two byte value */
+        checksum = (checksum >> 16) + (checksum & 0xFFFF);
+
+        /* Do it again in case previous operation generates an overflow */
+        checksum = (checksum >> 16) + (checksum & 0xFFFF);
+
+        /* Convert to network byte order. */
+        tmp = (USHORT)checksum;
+        NX_CHANGE_USHORT_ENDIAN(tmp);
+        checksum = tmp;
+    }
+
+    /* Now we need to go through the payloads */
+
+    /* Setup the pointer to the start of the packet.  */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    long_ptr =  (ULONG *)packet_ptr -> nx_packet_prepend_ptr;
+
+    /* Initialize the current packet to the input packet pointer.  */
+    current_packet =  packet_ptr;
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+    /* Loop the packet. */
+    while (current_packet)
+    {
+
+        /* Calculate current packet size. */
+        /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+        packet_size = (ULONG)(current_packet -> nx_packet_append_ptr - current_packet -> nx_packet_prepend_ptr);
+
+        /* Calculate the end address in this packet. */
+        if (data_length > (UINT)packet_size)
+        {
+
+            /*lint -e{927} -e{923} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+            end_ptr = ((ALIGN_TYPE)current_packet -> nx_packet_append_ptr) & (ALIGN_TYPE)(~3);
+        }
+        else
+        {
+#endif /* NX_DISABLE_PACKET_CHAIN */
+            /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+            end_ptr = (ALIGN_TYPE)current_packet -> nx_packet_prepend_ptr + data_length - 3;
+#ifndef NX_DISABLE_PACKET_CHAIN
+        }
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+        /* Set the start address in this packet. */
+        /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        long_ptr = (ULONG *)current_packet -> nx_packet_prepend_ptr;
+
+        /*lint -e{946} suppress pointer subtraction, since it is necessary. */
+        if ((ALIGN_TYPE)long_ptr < end_ptr)
+        {
+
+            /* Calculate the data_length. */
+            /*lint -e{923} suppress cast of pointer to ULONG.  */
+            data_length -= (UINT)(((end_ptr + 3) & (ALIGN_TYPE)(~3llu)) - (ALIGN_TYPE)long_ptr);
+
+            /* Loop to calculate the packet's checksum.  */
+            /*lint -e{946} suppress pointer subtraction, since it is necessary. */
+            while ((ALIGN_TYPE)long_ptr < end_ptr)
+            {
+                checksum += (*long_ptr & NX_LOWER_16_MASK);
+                checksum += (*long_ptr >> NX_SHIFT_BY_16);
+                long_ptr++;
+            }
+        }
+#ifndef NX_DISABLE_PACKET_CHAIN
+
+        /* Determine if we are at the end of the current packet.  */
+        if ((data_length > 0) && (current_packet -> nx_packet_next))
+        {
+
+            /* Is append_ptr two bytes aligned but not four bytes aligned? */
+            /*lint -e{923} suppress cast of pointer to ULONG.  */
+            if ((((ALIGN_TYPE)current_packet -> nx_packet_append_ptr) & 3) == 2)
+            {
+
+                /* Yes it is. Process the last two bytes in chaining packets. */
+                /*lint -e{929} -e{740} suppress cast of pointer to pointer, since it is necessary  */
+                short_ptr = (USHORT *)long_ptr;
+
+                /*lint -e{929} -e{740} suppress cast of pointer to pointer, since it is necessary  */
+                checksum += *short_ptr;
+                data_length -= 2;
+            }
+
+            /* We have crossed the packet boundary.  Move to the next packet
+               structure.  */
+            current_packet =  current_packet -> nx_packet_next;
+        }
+        else
+        {
+
+            /* End the loop.  */
+            current_packet = NX_NULL;
+        }
+    }
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+    /* Determine if there is only one byte left. */
+    if (data_length)
+    {
+
+        /* Set the short_ptr. */
+        short_ptr = (USHORT *)(long_ptr);
+
+        /* Check the data length.  */
+        if (data_length == 1)
+        {
+            *((UCHAR *)short_ptr + 1) = 0;
+        }
+        else if (data_length == 3)
+        {
+            checksum += *short_ptr;
+            short_ptr++;
+
+            *((UCHAR *)short_ptr + 1) = 0;
+        }
+
+        checksum += *short_ptr;
+    }
+
+    /* Fold a 4-byte value into a two byte value */
+    checksum = (checksum >> 16) + (checksum & 0xFFFF);
+
+    /* Do it again in case previous operation generates an overflow */
+    checksum = (checksum >> 16) + (checksum & 0xFFFF);
+
+    /* Convert to host byte order. */
+    tmp = (USHORT)checksum;
+    NX_CHANGE_USHORT_ENDIAN(tmp);
+
+    /* Return the computed checksum.  */
+    return(tmp);
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_create.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_create.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_create.c	(revision 69)
@@ -0,0 +1,304 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_system.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_create                                       PORTABLE C      */
+/*                                                           6.3.0        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function creates an Internet Protocol instance, including      */
+/*    setting up all appropriate data structures and calling the supplied */
+/*    link driver for initialization of the physical interface.           */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    name                                  Name of this IP instance      */
+/*    ip_address                            Internet address for this IP  */
+/*    network_mask                          Network mask for IP address   */
+/*    default_pool                          Default packet pool           */
+/*    ip_link_driver                        User supplied IP link driver  */
+/*    memory_ptr                            Pointer memory area for IP    */
+/*    memory_size                           Size of IP memory area        */
+/*    priority                              Priority of IP helper thread  */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Completion status             */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    tx_event_flags_create                 Create IP event flags         */
+/*    tx_event_flags_delete                 Delete IP event flags         */
+/*    tx_mutex_create                       Create IP protection mutex    */
+/*    tx_mutex_delete                       Delete IP protection mutex    */
+/*    tx_thread_create                      Create IP helper thread       */
+/*    tx_timer_create                       Create IP periodic timer      */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application                                                         */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  10-31-2023     Tiejun Zhou              Modified comment(s),          */
+/*                                            supported random IP id,     */
+/*                                            resulting in version 6.3.0  */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nx_ip_create(NX_IP *ip_ptr, CHAR *name, ULONG ip_address, ULONG network_mask,
+                    NX_PACKET_POOL *default_pool, VOID (*ip_link_driver)(struct NX_IP_DRIVER_STRUCT *),
+                    VOID *memory_ptr, ULONG memory_size, UINT priority)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+NX_IP     *tail_ptr;
+UINT       i;
+UINT       old_threshold = 0;
+TX_THREAD *current_thread;
+
+#ifdef NX_DISABLE_IPV4
+    NX_PARAMETER_NOT_USED(ip_address);
+    NX_PARAMETER_NOT_USED(network_mask);
+#endif /* NX_DISABLE_IPV4 */
+
+    /* Reference the version ID and option words to ensure they are linked in.  */
+    if (((ULONG)_nx_system_build_options_1 | (ULONG)_nx_system_build_options_2 | (ULONG)_nx_system_build_options_3 |
+         (ULONG)_nx_system_build_options_4 | (ULONG)_nx_system_build_options_5 | (ULONG)_nx_version_id[0]) == 0)
+    {
+
+        /* We should never get here!  */
+        return(NX_NOT_IMPLEMENTED);
+    }
+
+    /* Initialize the IP control block to zero.  */
+    memset((void *)ip_ptr, 0, sizeof(NX_IP));
+
+    /* Configure the primary interface. */
+    ip_ptr -> nx_ip_interface[0].nx_interface_valid = 1;
+
+#ifndef NX_DISABLE_IPV4
+    /* Save the IP address.  */
+    ip_ptr -> nx_ip_interface[0].nx_interface_ip_address =   ip_address;
+
+    /* Save the network mask.  */
+    ip_ptr -> nx_ip_interface[0].nx_interface_ip_network_mask =  network_mask;
+
+    /* Derive the network bits of this IP address.  */
+    ip_ptr -> nx_ip_interface[0].nx_interface_ip_network =  ip_address & network_mask;
+
+    /* Initialize the ARP defend timeout.  */
+    ip_ptr -> nx_ip_interface[0].nx_interface_arp_defend_timeout = 0;
+#endif /* !NX_DISABLE_IPV4  */
+
+    /* Setup the link driver address.  */
+    ip_ptr -> nx_ip_interface[0].nx_interface_link_driver_entry =  ip_link_driver;
+
+    /* Set the device interface name to "PRI". */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    ip_ptr -> nx_ip_interface[0].nx_interface_name = (CHAR *)"PRI";
+
+    /* Set index of each interface. */
+    for (i = 0; i < NX_MAX_IP_INTERFACES; i++)
+    {
+        ip_ptr -> nx_ip_interface[i].nx_interface_index = (UCHAR)i;
+    }
+
+
+#ifndef NX_DISABLE_LOOPBACK_INTERFACE
+
+    /* Set the Loopback interface name. */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_name = (CHAR *)"Internal IP Loopback";
+
+
+    /* Mark the loopback interface as valid. */
+    ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_valid = 1;
+
+#ifndef NX_DISABLE_IPV4
+    /* Set the loopback interface address. */
+    ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_ip_address = 0x7F000001;
+    ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_ip_network_mask = 0xFF000000;
+    ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_ip_network = 0x7F000000;
+#endif /* !NX_DISABLE_IPV4  */
+
+    /* Loopback interface is a special case. Therefore no dedicated link driver needed. */
+    ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_link_driver_entry = NX_NULL;
+
+    /* Loopback interface does not need IP/MAC address mapping. */
+    ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_address_mapping_needed = 0;
+
+    /* There is actually no MTU limit for the loopback interface. */
+    ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_ip_mtu_size = 65535;
+
+    /* Mark the loopback interface as LINK UP */
+    ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_link_up = 1;
+
+    /* Set all the link capability. */
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nx_interface_capability_flag = (NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM |
+                                                                                     NX_INTERFACE_CAPABILITY_IPV4_RX_CHECKSUM |
+                                                                                     NX_INTERFACE_CAPABILITY_TCP_TX_CHECKSUM |
+                                                                                     NX_INTERFACE_CAPABILITY_TCP_RX_CHECKSUM |
+                                                                                     NX_INTERFACE_CAPABILITY_UDP_TX_CHECKSUM |
+                                                                                     NX_INTERFACE_CAPABILITY_UDP_RX_CHECKSUM |
+                                                                                     NX_INTERFACE_CAPABILITY_ICMPV4_TX_CHECKSUM |
+                                                                                     NX_INTERFACE_CAPABILITY_ICMPV4_RX_CHECKSUM |
+                                                                                     NX_INTERFACE_CAPABILITY_ICMPV6_RX_CHECKSUM |
+                                                                                     NX_INTERFACE_CAPABILITY_ICMPV6_TX_CHECKSUM |
+                                                                                     NX_INTERFACE_CAPABILITY_IGMP_TX_CHECKSUM |
+                                                                                     NX_INTERFACE_CAPABILITY_IGMP_RX_CHECKSUM);
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+#endif /* !NX_DISABLE_LOOPBACK_INTERFACE */
+
+    /* Save the supplied IP name.  */
+    ip_ptr -> nx_ip_name =  name;
+
+    /* Set the initial IP packet ID.  */
+#ifndef NX_ENABLE_IP_ID_RANDOMIZATION
+    ip_ptr -> nx_ip_packet_id =  NX_INIT_PACKET_ID;
+#endif /* NX_ENABLE_IP_ID_RANDOMIZATION */
+
+    /* Setup the default packet pool for this IP instance.  */
+    ip_ptr -> nx_ip_default_packet_pool =  default_pool;
+
+#ifdef NX_ENABLE_DUAL_PACKET_POOL
+    /* Setup the auxiliary packet pool for this IP instance. By default it pointers to default pool. */
+    ip_ptr -> nx_ip_auxiliary_packet_pool = default_pool;
+#endif /* NX_ENABLE_DUAL_PACKET_POOL */
+
+    /* Create the internal IP protection mutex.  */
+    tx_mutex_create(&(ip_ptr -> nx_ip_protection), name, TX_NO_INHERIT);
+
+    /* Create the internal IP event flag object.  */
+    tx_event_flags_create(&(ip_ptr -> nx_ip_events), name);
+
+    /* Pickup current thread pointer.  */
+    current_thread =  tx_thread_identify();
+
+    /* Disable preemption temporarily.  */
+    if (current_thread)
+    {
+        tx_thread_preemption_change(current_thread, priority, &old_threshold);
+    }
+
+    /* Create the internal IP thread for handling more processing intensive
+       duties.  */
+    /*lint -e{923} suppress cast of pointer to ULONG.  */
+    tx_thread_create(&(ip_ptr -> nx_ip_thread), name, _nx_ip_thread_entry, (ULONG)(ALIGN_TYPE)(ip_ptr),
+                     memory_ptr, memory_size, priority, priority, 1, TX_AUTO_START);
+
+    NX_THREAD_EXTENSION_PTR_SET(&(ip_ptr -> nx_ip_thread), ip_ptr)
+
+    /* Create the periodic timer for this IP instance.  */
+    /*lint -e{923} suppress cast of pointer to ULONG.  */
+    tx_timer_create(&(ip_ptr -> nx_ip_periodic_timer), name,
+                    _nx_ip_periodic_timer_entry, (ULONG)(ALIGN_TYPE)ip_ptr,
+                    NX_IP_PERIODIC_RATE, NX_IP_PERIODIC_RATE, TX_AUTO_ACTIVATE);
+
+    NX_TIMER_EXTENSION_PTR_SET(&(ip_ptr -> nx_ip_periodic_timer), ip_ptr)
+
+    /* If trace is enabled, register this object.  */
+    NX_TRACE_OBJECT_REGISTER(NX_TRACE_OBJECT_TYPE_IP, ip_ptr, name, memory_ptr, memory_size);
+
+    /* If trace is enabled, insert this event into the trace buffer.  */
+    NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_CREATE, ip_ptr, ip_address, network_mask, default_pool, NX_TRACE_IP_EVENTS, 0, 0);
+
+#ifndef NX_DISABLE_IPV4
+    /* Install IPv4 packet receive processing function pointer */
+    ip_ptr -> nx_ipv4_packet_receive = _nx_ipv4_packet_receive;
+#endif
+
+    /* Otherwise, the IP initialization was successful.  Place the
+       IP control block on the list of created IP instances.  */
+    TX_DISABLE
+
+    /* Load the IP ID field in the IP control block.  */
+    ip_ptr -> nx_ip_id =  NX_IP_ID;
+
+    /* Place the new IP control block on the list of created IPs.  First,
+       check for an empty list.  */
+    if (_nx_ip_created_ptr)
+    {
+
+        /* Pickup tail pointer.  */
+        tail_ptr =  _nx_ip_created_ptr -> nx_ip_created_previous;
+
+        /* Place the new IP control block in the list.  */
+        _nx_ip_created_ptr -> nx_ip_created_previous =  ip_ptr;
+        tail_ptr -> nx_ip_created_next =  ip_ptr;
+
+        /* Setup this IP's created links.  */
+        ip_ptr -> nx_ip_created_previous =  tail_ptr;
+        ip_ptr -> nx_ip_created_next =      _nx_ip_created_ptr;
+    }
+    else
+    {
+
+        /* The created IP list is empty.  Add IP control block to empty list.  */
+        _nx_ip_created_ptr =                ip_ptr;
+        ip_ptr -> nx_ip_created_next =      ip_ptr;
+        ip_ptr -> nx_ip_created_previous =  ip_ptr;
+    }
+
+    /* Increment the created IP counter.  */
+    _nx_ip_created_count++;
+
+    /* Restore previous interrupt posture.  */
+    TX_RESTORE
+
+    /* Restore preemption.  */
+    if (current_thread)
+    {
+
+        /*lint -e{644} suppress variable might not be initialized, since "old_threshold" was initialized in previous tx_thread_preemption_change call. */
+        tx_thread_preemption_change(current_thread, old_threshold, &old_threshold);
+    }
+
+    /* Return success to the caller.  */
+    return(NX_SUCCESS);
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_deferred_link_status_process.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_deferred_link_status_process.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_deferred_link_status_process.c	(revision 69)
@@ -0,0 +1,124 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+/* Include necessary system files. */
+#include "nx_api.h"
+#include "nx_tcp.h"
+#include "nx_arp.h"
+#include "nx_icmpv6.h"
+#include "nx_link.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_diferred_link_status_process                 PORTABLE C      */
+/*                                                           6.4.0        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function processes link status change event.                   */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    tx_mutex_get                          Obtain protection mutex       */
+/*    tx_mutex_put                          Release protection mutex      */
+/*    _nx_tcp_socket_connection_reset       Reset TCP connection          */
+/*    _nx_arp_interface_entries_delete      Remove specified ARP entries  */
+/*    _nx_nd_cache_interface_entries_delete Delete ND cache entries assoc-*/
+/*                                          iated with specified interface*/
+/*    link_driver_entry                     Link driver                   */
+/*    memset                                Zero out the interface        */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    nx_ip_thread_entry                                                  */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  12-31-2023     Yajun Xia                Modified comment(s),          */
+/*                                            supported VLAN and generic  */
+/*                                            link layer,                 */
+/*                                            resulting in version 6.4.0  */
+/*                                                                        */
+/**************************************************************************/
+VOID _nx_ip_deferred_link_status_process(NX_IP *ip_ptr)
+{
+
+UINT         i;
+NX_IP_DRIVER driver_request;
+ULONG        link_up;
+
+    if (ip_ptr -> nx_ip_link_status_change_callback == NX_NULL)
+    {
+
+        /* Callback function is not set. */
+        return;
+    }
+
+    for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
+    {
+        if ((ip_ptr -> nx_ip_interface[i].nx_interface_valid) &&
+            (ip_ptr -> nx_ip_interface[i].nx_interface_link_status_change))
+        {
+
+            /* Reset the flag. */
+            ip_ptr -> nx_ip_interface[i].nx_interface_link_status_change = NX_FALSE;
+
+            driver_request.nx_ip_driver_ptr       = ip_ptr;
+            driver_request.nx_ip_driver_command   = NX_LINK_GET_STATUS;
+            driver_request.nx_ip_driver_interface = &(ip_ptr -> nx_ip_interface[i]);
+            driver_request.nx_ip_driver_return_ptr = &link_up;
+
+            (ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
+
+            /* Invoke the callback function. */
+            /*lint -e{644} suppress variable might not be initialized, since "link_up" was initialized in nx_interface_link_driver_entry. */
+            ip_ptr -> nx_ip_link_status_change_callback(ip_ptr, i, link_up);
+
+#ifdef NX_ENABLE_VLAN
+            /* Link status change need to propagate to vlan sub interface */
+            nx_link_vlan_interface_status_change(ip_ptr, i);
+#endif /* NX_ENABLE_VLAN */
+        }
+    }
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_dispatch_process.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_dispatch_process.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_dispatch_process.c	(revision 69)
@@ -0,0 +1,722 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_ipv6.h"
+#include "nx_icmp.h"
+#include "nx_packet.h"
+
+
+#ifdef NX_IPSEC_ENABLE
+#include "nx_ipsec.h"
+#endif
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_dispatch_process                             PORTABLE C      */
+/*                                                           6.1.9        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function goes through IP header and option fields, and         */
+/*    dispatches into various process routines depending on the header    */
+/*    options.                                                            */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP instance        */
+/*    packet_ptr                            Incoming IP packet            */
+/*    protocol                              The first protocol immediately*/
+/*                                            following IP header         */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    Status                                0: do not drop packet         */
+/*                                          1: drop packet                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    [nx_ip_icmpv6_packet_process]         ICMPv6 header process         */
+/*    [nx_ip_tcp_packet_receive]            TCP packet process            */
+/*    [nx_ip_udp_packet_receive]            UDP packet process            */
+/*                                            ICMP ping request           */
+/*    _nx_ipv6_process_hop_by_hop_option    IPv6 hop by hop option        */
+/*                                            process                     */
+/*    NX_ICMPV6_SEND_PARAMETER_PROBELM      Send ICMP parameter problem   */
+/*    _nx_ipv6_process_routing_option       IPv6 routing option process   */
+/*    _nx_ipv6_process_fragment_option      IPv6 fragment option process  */
+/*    [nx_ipsec_authentication_header_receive]                            */
+/*                                          IPSec authentication header   */
+/*                                            process                     */
+/*    [nx_ipsec_encapsulating_security_payload_receive                    */
+/*                                          IPSec encapsulating security  */
+/*                                            payload process             */
+/*    (ip_icmp_packet_receive)              Receive a ICMP packet         */
+/*    (ip_igmp_packet_receive)              Receive a IGMP packet         */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s), fixed    */
+/*                                            destination header check,   */
+/*                                            resulting in version 6.1    */
+/*  10-15-2021     Yuxin Zhou               Modified comment(s), expanded */
+/*                                            protocols support for raw   */
+/*                                            packet,                     */
+/*                                            resulting in version 6.1.9  */
+/*                                                                        */
+/**************************************************************************/
+UINT _nx_ip_dispatch_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UINT protocol)
+{
+
+UINT              drop_packet;
+
+#ifdef FEATURE_NX_IPV6
+NXD_IPV6_ADDRESS *incoming_addr;
+UINT              next_option_offset;
+
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+UINT              nx_packet_option_offset;
+#endif /* NX_DISABLE_ICMPV6_ERROR_MESSAGE  */
+#endif /* FEATURE_NX_IPV6 */
+
+#ifdef NX_IPSEC_ENABLE
+UINT              ret;
+ULONG             next_protocol = 0;
+NXD_ADDRESS       src_addr, dest_addr;
+#ifndef NX_DISABLE_IPV4
+NX_IPV4_HEADER   *ipv4_header;
+#endif /* NX_DISABLE_IPV4 */
+#ifdef FEATURE_NX_IPV6
+NX_IPV6_HEADER   *ipv6_header;
+NX_ICMPV6_HEADER *icmp_header_ptr;
+#endif /* FEATURE_NX_IPV6 */
+#endif /* NX_IPSEC_ENABLE */
+
+
+    /* Initialize local variables. */
+    drop_packet = 0;
+#ifdef FEATURE_NX_IPV6
+    next_option_offset = (UINT)sizeof(NX_IPV6_HEADER);
+    incoming_addr = packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr;
+#endif /* FEATURE_NX_IPV6 */
+
+    /* Parse all options in the packet till we're done or an error is encountered. */
+    while (!drop_packet)
+    {
+
+        /* Add debug information. */
+        NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ERROR_MESSAGE)
+        /* Set a local variable for convenience. */
+        nx_packet_option_offset = packet_ptr -> nx_packet_option_offset;
+#endif /* defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ERROR_MESSAGE) */
+        switch (protocol)
+        {
+
+#ifdef FEATURE_NX_IPV6
+        case NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP:
+
+            /* This should be the first header; if it is not, this is a malformed packet. */
+            if (packet_ptr -> nx_packet_option_state >= (UCHAR)HOP_BY_HOP_HEADER)
+            {
+
+                drop_packet = 1;
+
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+                NX_ICMPV6_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, 1, nx_packet_option_offset);
+#endif /* NX_DISABLE_ICMPV6_ERROR_MESSAGE */
+            }
+            else
+            {
+
+                /* Start the option header handling. */
+                packet_ptr -> nx_packet_option_state = (UCHAR)HOP_BY_HOP_HEADER;
+
+                /* Dispatch packet to the Option handler. */
+                drop_packet = _nx_ipv6_process_hop_by_hop_option(ip_ptr, packet_ptr);
+            }
+
+            break;
+
+        case NX_PROTOCOL_NEXT_HEADER_DESTINATION:
+
+            /* Invalid header option if we have already processed 1 destination option. */
+            if (packet_ptr -> nx_packet_destination_header >= 1)
+            {
+
+                /* If we already have processed one destination option, we expect this
+                   to be the second one. */
+                if ((packet_ptr -> nx_packet_option_state < (UCHAR)DESTINATION_HEADER_1) ||
+                    (packet_ptr -> nx_packet_destination_header > 1))
+                {
+                    drop_packet = 1;
+                }
+                else
+                {
+                    packet_ptr -> nx_packet_option_state = (UCHAR)DESTINATION_HEADER_2;
+                }
+            }
+            else
+            {
+
+                /* This is the first time we encounter a destination header option. */
+                /* If we are before the routing header option, this must be the 1st one.
+                   Otherwise, it must be the 2nd one. */
+
+                if (packet_ptr -> nx_packet_option_state < (UCHAR)ROUTING_HEADER)
+                {
+
+                    packet_ptr -> nx_packet_option_state = (UCHAR)DESTINATION_HEADER_1;
+                }
+                else
+                {
+                    packet_ptr -> nx_packet_option_state = (UCHAR)DESTINATION_HEADER_2;
+                }
+            }
+
+            packet_ptr -> nx_packet_destination_header++;
+
+            if (!drop_packet)
+            {
+                /* Proceed with hop by hop handling if there are no errors. */
+                drop_packet = _nx_ipv6_process_hop_by_hop_option(ip_ptr, packet_ptr);
+            }
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+            else
+            {
+
+                /* Return an error message to the sender of the packet. */
+                NX_ICMPV6_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, 1, nx_packet_option_offset);
+            }
+#endif /* NX_DISABLE_ICMPV6_ERROR_MESSAGE */
+
+            break;
+
+        case NX_PROTOCOL_NEXT_HEADER_ROUTING:
+
+            if (packet_ptr -> nx_packet_option_state >= (UCHAR)ROUTING_HEADER)
+            {
+
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+                NX_ICMPV6_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, 1, nx_packet_option_offset);
+#endif /* NX_DISABLE_ICMPV6_ERROR_MESSAGE */
+
+                drop_packet = 1;
+            }
+            else
+            {
+
+                packet_ptr -> nx_packet_option_state = (UCHAR)ROUTING_HEADER;
+
+                drop_packet = _nx_ipv6_process_routing_option(ip_ptr, packet_ptr);
+            }
+            break;
+
+        case NX_PROTOCOL_NEXT_HEADER_FRAGMENT:
+
+#ifndef NX_DISABLE_FRAGMENTATION
+            if (packet_ptr -> nx_packet_option_state >= (UCHAR)FRAGMENT_HEADER)
+            {
+#endif /* NX_DISABLE_FRAGMENTATION */
+
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+                NX_ICMPV6_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, 1, nx_packet_option_offset);
+#endif /* NX_DISABLE_ICMPV6_ERROR_MESSAGE */
+
+                drop_packet = 1;
+#ifndef NX_DISABLE_FRAGMENTATION
+            }
+            else
+            {
+
+                packet_ptr -> nx_packet_option_state = (UCHAR)FRAGMENT_HEADER;
+
+#ifdef NX_ENABLE_LOW_WATERMARK
+                if (packet_ptr -> nx_packet_pool_owner -> nx_packet_pool_available >=
+                    packet_ptr -> nx_packet_pool_owner -> nx_packet_pool_low_watermark)
+#endif
+                {
+                    drop_packet = _nx_ipv6_process_fragment_option(ip_ptr, packet_ptr);
+                }
+#ifdef NX_ENABLE_LOW_WATERMARK
+                else
+                {
+                    drop_packet = NX_POOL_ERROR;
+                }
+#endif
+
+                if (drop_packet != NX_CONTINUE)
+                {
+
+                    /* Special case: do not further process the packet here.
+                       Once all fragments are received, we will continue processing the headers. */
+                    return(drop_packet);
+                }
+                else
+                {
+
+                    /* Continue processing the packet. */
+                    drop_packet = 0;
+                }
+            }
+#endif /* NX_DISABLE_FRAGMENTATION */
+            break;
+
+        case NX_PROTOCOL_NO_NEXT_HEADER:
+
+            drop_packet = 1;
+            break;
+
+#endif /* FEATURE_NX_IPV6 */
+
+        case NX_PROTOCOL_NEXT_HEADER_AUTHENTICATION:
+
+#ifdef NX_IPSEC_ENABLE
+            if (ip_ptr -> nx_ip_ipsec_authentication_header_receive == NX_NULL)
+            {
+
+                /* If IPsec is not enabled by the application, drop the packet. */
+                return(1);
+            }
+            else
+            {
+
+                ret =  ip_ptr -> nx_ip_ipsec_authentication_header_receive(ip_ptr, packet_ptr, &next_protocol, &packet_ptr);
+
+                if (ret == NX_SUCCESS)
+                {
+
+                    /* Indicate that IPSec consumed the packet. */
+                    return(0);
+                }
+
+                if (ret != NX_IPSEC_PKT_CONT)
+                {
+
+                    return(1);
+                }
+
+                /* Continue processing the packet if status = NX_IPSEC_PKT_CONT */
+            }
+#else /* NX_IPSEC_ENABLE */
+
+            /* Drop this packet if IPsec module is not present. */
+            drop_packet = 1;
+#endif /* NX_IPSEC_ENABLE */
+
+            break;
+
+        case NX_PROTOCOL_NEXT_HEADER_ENCAP_SECURITY:
+
+#ifdef NX_IPSEC_ENABLE
+            if (ip_ptr -> nx_ip_ipsec_encapsulating_security_payload_receive == NX_NULL)
+            {
+
+                /* If IPsec is not enabled by the application, drop the packet. */
+                return(1);
+            }
+            else
+            {
+
+                ret =  ip_ptr -> nx_ip_ipsec_encapsulating_security_payload_receive(ip_ptr, packet_ptr, &next_protocol, &packet_ptr);
+
+                if (ret == NX_SUCCESS)
+                {
+
+                    /* Indicate IPSec consumed the packet. */
+                    return(0);
+                }
+
+                if (ret != NX_IPSEC_PKT_CONT)
+                {
+                    return(1);
+                }
+
+                /* Continue processing the packet if status = NX_IPSEC_PKT_CONT */
+            }
+            break;
+
+#else /* NX_IPSEC_ENABLE */
+            /* Drop this packet if IPsec module is not present. */
+            return(1);
+#endif /* NX_IPSEC_ENABLE */
+
+        default:
+
+            /* Not part of the IP headers. */
+#ifdef NX_IPSEC_ENABLE
+            /* Check ingress_sa for packet that is not ESP or AH.  */
+            if (packet_ptr -> nx_packet_ipsec_sa_ptr == NX_NULL)
+            {
+
+                /* Get source and destination address.  */
+#ifdef FEATURE_NX_IPV6
+                if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6)
+                {
+                    ipv6_header = (NX_IPV6_HEADER *)(packet_ptr -> nx_packet_ip_header);
+
+                    src_addr.nxd_ip_version = NX_IP_VERSION_V6;
+                    dest_addr.nxd_ip_version = NX_IP_VERSION_V6;
+
+                    COPY_IPV6_ADDRESS(ipv6_header -> nx_ip_header_source_ip,
+                                      src_addr.nxd_ip_address.v6);
+
+
+                    COPY_IPV6_ADDRESS(ipv6_header -> nx_ip_header_destination_ip,
+                                      dest_addr.nxd_ip_address.v6);
+                }
+                else
+#endif /* FEATURE_NX_IPV6 */
+                {
+#ifndef NX_DISABLE_IPV4
+                    ipv4_header = (NX_IPV4_HEADER *)(packet_ptr -> nx_packet_ip_header);
+
+                    src_addr.nxd_ip_version = NX_IP_VERSION_V4;
+                    dest_addr.nxd_ip_version = NX_IP_VERSION_V4;
+
+                    src_addr.nxd_ip_address.v4 = ipv4_header -> nx_ip_header_source_ip;
+                    dest_addr.nxd_ip_address.v4 = ipv4_header -> nx_ip_header_destination_ip;
+#endif /* NX_DISABLE_IPV4 */
+                }
+
+                if (_nx_ipsec_sa_ingress_lookup(ip_ptr, &src_addr, &dest_addr, 0, (UCHAR)protocol,
+                                                NX_NULL, packet_ptr -> nx_packet_prepend_ptr) != NX_IPSEC_TRAFFIC_BYPASS)
+                {
+#ifdef FEATURE_NX_IPV6
+                    /* Check whether it is a NA packet.  */
+                    if (protocol == NX_PROTOCOL_ICMPV6)
+                    {
+
+                        /* Bypass NA packet. */
+                        icmp_header_ptr = (NX_ICMPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
+                        if (icmp_header_ptr -> nx_icmpv6_header_type != NX_ICMPV6_NEIGHBOR_ADVERTISEMENT_TYPE)
+                        {
+                            return(NX_INVALID_PACKET);
+                        }
+                    }
+                    else
+                    {
+#endif /* FEATURE_NX_IPV6 */
+                        return(NX_INVALID_PACKET);
+#ifdef FEATURE_NX_IPV6
+                    }
+#endif /* FEATURE_NX_IPV6 */
+                }
+            }
+            /* For IPsec tunnel mode, next protocol is checked here. */
+            else if (((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_sa_mode == NX_IPSEC_TUNNEL_MODE)
+            {
+                if (_nx_ipsec_sa_ingress_selector_check(packet_ptr -> nx_packet_prepend_ptr,
+                                                        (UCHAR)protocol,
+                                                        ((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_selector_ptr) == NX_IPSEC_TRAFFIC_DROP)
+                {
+                    _nx_packet_release(packet_ptr);     /* Consume the packet */
+                    return(NX_INVALID_PACKET);
+                }
+            }
+#endif /* NX_IPSEC_ENABLE */
+
+#if defined(NX_ENABLE_IP_RAW_PACKET_ALL_STACK) && defined(NX_ENABLE_IP_RAW_PACKET_FILTER)
+            if ((ip_ptr -> nx_ip_raw_ip_processing) && (ip_ptr -> nx_ip_raw_packet_filter))
+            {
+
+                /* Let RAW packet filter handler filter all incoming packets.  */
+                if ((ip_ptr -> nx_ip_raw_ip_processing)(ip_ptr, protocol << 16, packet_ptr) == NX_SUCCESS)
+                {
+                    /* No need to free the packet as it is consumed by the raw process */
+                    return(0);
+                }
+            }
+#endif /* defined(NX_ENABLE_IP_RAW_PACKET_ALL_STACK) && defined(NX_ENABLE_IP_RAW_PACKET_FILTER) */
+
+            if (protocol == NX_PROTOCOL_TCP)
+            {
+#ifdef FEATURE_NX_IPV6
+                if ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) ||
+                    ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) &&
+                     (incoming_addr -> nxd_ipv6_address_state == NX_IPV6_ADDR_STATE_VALID)))
+                {
+#endif /* FEATURE_NX_IPV6 */
+
+                    /* Check that the host is enabled for TCP. */
+                    if (ip_ptr -> nx_ip_tcp_packet_receive)
+                    {
+
+                        /* Dispatch the packet to the TCP packet handler. */
+                        (ip_ptr -> nx_ip_tcp_packet_receive)(ip_ptr, packet_ptr);
+
+                        /* No need to free the packet as it is consumed by TCP packet receive.  */
+                        return(0);
+                    }
+#ifdef FEATURE_NX_IPV6
+                }
+#endif /* FEATURE_NX_IPV6 */
+
+                /* TCP is not enabled.  Drop the packet. */
+                drop_packet = 1;
+            }
+
+#ifdef FEATURE_NX_IPV6
+            else if ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) &&
+                     (protocol == NX_PROTOCOL_ICMPV6))
+            {
+
+                /* Check that ICMPv6 is enabled for this IP instance.  */
+                if (ip_ptr -> nx_ip_icmpv6_packet_process != NX_NULL)
+                {
+
+                    /* Forward to the ICMPv6 packet handler. */
+                    ip_ptr -> nx_ip_icmpv6_packet_process(ip_ptr, packet_ptr);
+
+                    /*  no need to free packet as it is consumed by ICMP packet receive.  */
+                    return(0);
+                }
+
+                /* ICMPv6 is not enabled.  Drop the packet. */
+                drop_packet = 1;
+            }
+#endif /* FEATURE_NX_IPV6 */
+
+#ifndef NX_DISABLE_IPV4
+            else if ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) &&
+                     (protocol == NX_PROTOCOL_ICMP))
+            {
+
+                /* Check that ICMP is enabled for this IP instance.  */
+                if (ip_ptr -> nx_ip_icmp_packet_receive != NX_NULL)
+                {
+
+                    /* Yes, a ICMP packet is present, dispatch to the appropriate ICMP handler
+                       if present.  */
+                    ip_ptr -> nx_ip_icmp_packet_receive(ip_ptr, packet_ptr);
+                    return(0);
+                }
+
+                /* ICMP is not enabled. Drop the packet. */
+                drop_packet = 1;
+            }
+            else if ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) &&
+                     (protocol == NX_PROTOCOL_IGMP))
+            {
+                if (ip_ptr -> nx_ip_igmp_packet_receive != NX_NULL)
+                {
+
+                    /* Yes, a IGMP packet is present, dispatch to the appropriate ICMP handler
+                       if present.  */
+                    ip_ptr -> nx_ip_igmp_packet_receive(ip_ptr, packet_ptr);
+                    return(0);
+                }
+
+                /* IGMP is not enabled. Drop the packet.  */
+                drop_packet = 1;
+            }
+#endif /* NX_DISABLE_IPV4 */
+            else if (protocol == NX_PROTOCOL_UDP)
+            {
+
+#ifdef FEATURE_NX_IPV6
+                if ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4) ||
+                    ((packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6) &&
+                     (incoming_addr -> nxd_ipv6_address_state == NX_IPV6_ADDR_STATE_VALID)))
+                {
+#endif /* FEATURE_NX_IPV6 */
+
+                    /* Check the host is enabled for UDP packet handling. */
+                    if (ip_ptr -> nx_ip_udp_packet_receive)
+                    {
+
+                        /* Dispatch the packet to the UDP handler. */
+                        (ip_ptr -> nx_ip_udp_packet_receive)(ip_ptr, packet_ptr);
+
+                        /* No need to free the packet as it is consumed by UDP packet receive.  */
+                        return(0);
+                    }
+#ifdef FEATURE_NX_IPV6
+                }
+#endif /* FEATURE_NX_IPV6 */
+
+                /* UDP is not enabled.  Drop the packet. */
+                drop_packet = 1;
+            }
+            else
+            {
+                if (ip_ptr -> nx_ip_raw_ip_processing)
+                {
+#if defined(NX_ENABLE_IP_RAW_PACKET_ALL_STACK) && defined(NX_ENABLE_IP_RAW_PACKET_FILTER)
+                    if (ip_ptr -> nx_ip_raw_packet_filter == NX_NULL)
+#endif /* defined(NX_ENABLE_IP_RAW_PACKET_ALL_STACK) && defined(NX_ENABLE_IP_RAW_PACKET_FILTER) */
+                    {
+                        if ((ip_ptr -> nx_ip_raw_ip_processing)(ip_ptr, protocol << 16, packet_ptr) == NX_SUCCESS)
+                        {
+                            /* No need to free the packet as it is consumed by the raw process */
+                            return(0);
+                        }
+                    }
+                }
+
+#if !defined(NX_DISABLE_IPV4) && !defined(NX_DISABLE_ICMPV4_ERROR_MESSAGE)
+                /* Unknown protocol, send ICMP Destination protocol unreachable. */
+                if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V4)
+                {
+                    NX_ICMPV4_SEND_DEST_UNREACHABLE(ip_ptr, packet_ptr, NX_ICMP_PROTOCOL_UNREACH_CODE);
+                }
+#endif /* !NX_DISABLE_IPV4 && !NX_DISABLE_ICMPV4_ERROR_MESSAGE  */
+
+#ifdef FEATURE_NX_IPV6
+                /* Unknown option.  Send ICMP Parameter problem and discard the packet. */
+                /* RFC 2460, page 7 */
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+                if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6)
+                {
+                    NX_ICMPV6_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, 1, nx_packet_option_offset);
+                }
+#endif /* NX_DISABLE_ICMPV6_ERROR_MESSAGE */
+#endif /* FEATURE_NX_IPV6 */
+
+#ifndef NX_DISABLE_IP_INFO
+
+                /* Increment the IP unknown protocol count.  */
+                ip_ptr -> nx_ip_unknown_protocols_received++;
+
+#endif /* NX_DISABLE_IP_INFO */
+
+
+                drop_packet = 1;
+            }
+            break;
+        }
+
+
+        /* If the previous header is processed without errors, move on to the next optional
+           header. */
+        if (!drop_packet)
+        {
+
+#ifdef FEATURE_NX_IPV6
+        NX_IPV6_HEADER_OPTION *option;
+        ULONG                  option_hdr_len;
+#endif /* FEATURE_NX_IPV6 */
+
+#ifdef NX_IPSEC_ENABLE
+
+            if (protocol == NX_PROTOCOL_NEXT_HEADER_ENCAP_SECURITY ||
+                protocol == NX_PROTOCOL_NEXT_HEADER_AUTHENTICATION)
+            {
+
+                /* After ESP and AH processing, ESP and AH hdr are removed. */
+                protocol = next_protocol;
+                continue;
+            }
+#endif  /* NX_IPSEC_ENABLE */
+
+#ifdef FEATURE_NX_IPV6
+            if (packet_ptr -> nx_packet_ip_version == NX_IP_VERSION_V6)
+            {
+
+                /* Find the option we just processed. */
+                /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+                option = (NX_IPV6_HEADER_OPTION *)packet_ptr -> nx_packet_prepend_ptr;
+
+                /* Check the protocol.  */
+                if (protocol == NX_PROTOCOL_NEXT_HEADER_FRAGMENT)
+                {
+
+                    /* Fixed length for fragment option, the field of option length is reserved.  */
+                    option_hdr_len = sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION);
+                }
+                else
+                {
+
+                    /* Compute the current option length. */
+                    /* For other IPv6 optional headers, hdr_ext_len is expressed in 64-bit words. */
+                    option_hdr_len = (ULONG)((option -> nx_ipv6_header_option_ext_length + 1) << 3);
+                }
+
+                /* Obtain the next option header type. */
+                protocol = option -> nx_ipv6_header_option_next_header;
+
+                if (((ALIGN_TYPE)(packet_ptr -> nx_packet_prepend_ptr) + option_hdr_len) <
+                    (ALIGN_TYPE)(packet_ptr -> nx_packet_append_ptr))
+                {
+
+                    /* Advance to the next header. */
+                    packet_ptr -> nx_packet_prepend_ptr += option_hdr_len;
+                    packet_ptr -> nx_packet_length      -= option_hdr_len;
+                }
+                else
+                {
+
+                    drop_packet = 1;
+                }
+
+                /*
+                   Advance the nx_packet_option_offset as well.
+                   Option Offset is used when constructing ICMPv6 parameter problem message.
+                 */
+
+                packet_ptr -> nx_packet_option_offset = (USHORT)next_option_offset;
+
+                /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+                next_option_offset = (UINT)(packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_ip_header);
+            }
+#endif /* FEATURE_NX_IPV6 */
+        }
+        else
+        {
+#ifndef NX_DISABLE_IP_INFO
+
+            /* Decrement the number of packets delivered.  */
+            ip_ptr -> nx_ip_total_packets_delivered--;
+
+            /* Decrement the IP packet bytes received (not including the header).  */
+            ip_ptr -> nx_ip_total_bytes_received -=  packet_ptr -> nx_packet_length;
+
+            /* Increment the IP receive packets dropped count.  */
+            ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif /* NX_DISABLE_IP_INFO */
+        }
+    }
+
+    return(drop_packet);
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_driver_packet_send.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_driver_packet_send.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_driver_packet_send.c	(revision 69)
@@ -0,0 +1,538 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_packet.h"
+
+#ifndef NX_DISABLE_IPV4
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_driver_packet_send                           PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function sends an IP packet to the appropriate link driver.    */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to packet to send     */
+/*    destination_ip                        Destination IP address        */
+/*    fragment                              Don't fragment bit            */
+/*    next_hop_address                      Next Hop address              */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    (_nx_arp_entry_allocate)              ARP entry allocate service    */
+/*    (_nx_arp_packet_send)                 Send an ARP packet            */
+/*    _nx_ip_packet_deferred_receive        Receive loopback packet       */
+/*    _nx_packet_copy                       Copy packet to input packet   */
+/*    _nx_packet_transmit_release           Release transmit packet       */
+/*    (nx_ip_fragment_processing)           Fragment processing           */
+/*    (ip_link_driver)                      User supplied link driver     */
+/*    _nx_ip_packet_checksum_compute        Compute checksum              */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID  _nx_ip_driver_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr, ULONG destination_ip, ULONG fragment, ULONG next_hop_address)
+{
+
+TX_INTERRUPT_SAVE_AREA
+NX_IP_DRIVER driver_request;
+UINT         index;
+ULONG        network_mask;
+ULONG        network;
+UCHAR        loopback = NX_FALSE;
+NX_ARP      *arp_ptr;
+NX_PACKET   *last_packet;
+NX_PACKET   *remove_packet;
+NX_PACKET   *packet_copy;
+UINT         queued_count;
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+    /* Initialize the driver request. */
+    driver_request.nx_ip_driver_ptr =                   ip_ptr;
+    driver_request.nx_ip_driver_packet =                packet_ptr;
+    driver_request.nx_ip_driver_interface =             packet_ptr -> nx_packet_address.nx_packet_interface_ptr;
+    driver_request.nx_ip_driver_command =               NX_LINK_PACKET_SEND;
+
+    /* Determine if physical mapping is needed by the link driver.  */
+    if (packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_address_mapping_needed)
+    {
+
+        /* Get the network and network mask.*/
+        network_mask = packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_ip_network_mask;
+        network = packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_ip_network;
+
+        /* Determine if an IP limited or directed broadcast is requested.  */
+        if ((destination_ip == NX_IP_LIMITED_BROADCAST) ||
+            (((destination_ip & network_mask) == network) &&
+             ((destination_ip & ~network_mask) == ~network_mask)))
+        {
+
+            /* Build the driver request.  */
+            driver_request.nx_ip_driver_command =               NX_LINK_PACKET_BROADCAST;
+            driver_request.nx_ip_driver_physical_address_msw =  0xFFFFUL;
+            driver_request.nx_ip_driver_physical_address_lsw =  0xFFFFFFFFUL;
+        }
+        /* Determine if we have a loopback address.  */
+        else if (destination_ip == packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_ip_address)
+        {
+            loopback = NX_TRUE;
+            driver_request.nx_ip_driver_interface = NX_NULL;
+        }
+        /* Determine if we have a class D multicast address.  */
+        else if ((destination_ip & NX_IP_CLASS_D_MASK) == NX_IP_CLASS_D_TYPE)
+        {
+
+            /* Yes, we have a class D multicast address.  Derive the physical mapping from
+               the class D address.  */
+
+            /* Determine if the group address has been joined in this IP instance.  */
+            index =  0;
+            while (index < NX_MAX_MULTICAST_GROUPS)
+            {
+
+                /* Determine if the destination address matches the requested address.  */
+                if (ip_ptr -> nx_ipv4_multicast_entry[index].nx_ipv4_multicast_join_list == destination_ip)
+                {
+
+                    /* Yes, break the loop!  */
+                    break;
+                }
+
+                /* Increment the join list index.  */
+                index++;
+            }
+
+            /* Determine if the group was joined by this IP instance.  */
+            if (index < NX_MAX_MULTICAST_GROUPS)
+            {
+
+                /* Determine if the group has loopback enabled.  */
+                if (ip_ptr -> nx_ipv4_multicast_entry[index].nx_ipv4_multicast_loopback_enable)
+                {
+                    loopback = NX_TRUE;
+                }
+            }
+
+            /* Build the driver request. Derive the physical mapping from
+               the class D address.  */
+            driver_request.nx_ip_driver_physical_address_msw =  NX_IP_MULTICAST_UPPER;
+            driver_request.nx_ip_driver_physical_address_lsw =  NX_IP_MULTICAST_LOWER | (destination_ip & NX_IP_MULTICAST_MASK);
+        }
+        else
+        {
+
+            NX_PARAMETER_NOT_USED(fragment);
+            /* Look into the ARP Routing Table to derive the physical address.  */
+
+            /* If we get here, the packet destination is a unicast address.  */
+            destination_ip = next_hop_address;
+
+            /* Calculate the hash index for the destination IP address.  */
+            index =  (UINT)((destination_ip + (destination_ip >> 8)) & NX_ARP_TABLE_MASK);
+
+            /* Determine if there is an entry for this IP address.  */
+            arp_ptr =  ip_ptr -> nx_ip_arp_table[index];
+
+            /* Loop to look for an ARP match.  */
+            while (arp_ptr)
+            {
+
+                /* Determine if this arp entry matches the destination IP address.  */
+                if (arp_ptr -> nx_arp_ip_address == destination_ip)
+                {
+
+                    /* Yes, we found a match.  Get out of the loop!  */
+                    break;
+                }
+
+                /* Move to the next active ARP entry.  */
+                arp_ptr =  arp_ptr -> nx_arp_active_next;
+
+                /* Determine if we are at the end of the ARP list.  */
+                if (arp_ptr == ip_ptr -> nx_ip_arp_table[index])
+                {
+                    /* Clear the ARP pointer.  */
+                    arp_ptr =  NX_NULL;
+                    break;
+                }
+            }
+
+            /* Determine if we actually found a matching and effective ARP entry.  */
+            if ((arp_ptr) && (arp_ptr -> nx_arp_physical_address_msw | arp_ptr -> nx_arp_physical_address_lsw))
+            {
+
+                /* Disable interrupts temporarily.  */
+                TX_DISABLE
+
+                /* Yes, we have a physical mapping.  Copy the physical address into the driver
+                   request structure.  */
+                driver_request.nx_ip_driver_physical_address_msw =  arp_ptr -> nx_arp_physical_address_msw;
+                driver_request.nx_ip_driver_physical_address_lsw =  arp_ptr -> nx_arp_physical_address_lsw;
+
+                /* Move this ARP entry to the head of the list.  */
+                ip_ptr -> nx_ip_arp_table[index] =  arp_ptr;
+
+                /* Restore interrupts.  */
+                TX_RESTORE
+            }
+            else
+            {
+
+                /* Determine if fragmentation is needed before queue the packet on the ARP waiting queue.  */
+                if (packet_ptr -> nx_packet_length > packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_ip_mtu_size)
+                {
+
+#ifndef NX_DISABLE_FRAGMENTATION
+                    /* Check the DF bit flag.  */
+                    if ((ip_ptr -> nx_ip_fragment_processing == NX_NULL) || (fragment != NX_FRAGMENT_OKAY))
+#endif
+                    {
+
+#ifndef NX_DISABLE_IP_INFO
+
+                        /* Increment the IP send packets dropped count.  */
+                        ip_ptr -> nx_ip_send_packets_dropped++;
+#endif
+                        /* Just release the packet.  */
+                        _nx_packet_transmit_release(packet_ptr);
+
+                        /* Return... nothing more can be done!  */
+                        return;
+                    }
+                }
+
+                /* Determine if we actually found a matching ARP entry.  */
+                if (arp_ptr)
+                {
+
+                    /* Yes, we have an existing ARP mapping entry.  */
+
+                    /* Disable interrupts temporarily.  */
+                    TX_DISABLE
+
+                    /* Ensure the current packet's queue next pointer to NULL.  */
+                    packet_ptr -> nx_packet_queue_next =  NX_NULL;
+
+                    /* Determine if the queue is empty.  */
+                    if (arp_ptr -> nx_arp_packets_waiting == NX_NULL)
+                    {
+
+                        /* Yes, we have an empty ARP packet queue.  Simply place the
+                           packet at the head of the list.  */
+                        arp_ptr -> nx_arp_packets_waiting =  packet_ptr;
+
+                        /* Add debug information. */
+                        NX_PACKET_DEBUG(NX_PACKET_ARP_WAITING_QUEUE, __LINE__, packet_ptr);
+
+                        /* Restore interrupts.  */
+                        TX_RESTORE
+                    }
+                    else
+                    {
+
+                        /* Determine how many packets are on the ARP entry's packet
+                           queue and remember the last packet in the queue.  We know
+                           there is at least one on the queue and another that is
+                           going to be queued.  */
+                        last_packet =  arp_ptr -> nx_arp_packets_waiting;
+                        queued_count = 1;
+                        while (last_packet -> nx_packet_queue_next)
+                        {
+
+                            /* Increment the queued count.  */
+                            queued_count++;
+
+                            /* Move to the next packet in the queue.  */
+                            last_packet =  last_packet -> nx_packet_queue_next;
+                        }
+
+                        /* Add debug information. */
+                        NX_PACKET_DEBUG(NX_PACKET_ARP_WAITING_QUEUE, __LINE__, packet_ptr);
+
+                        /* Place the packet at the end of the list.  */
+                        last_packet -> nx_packet_queue_next =  packet_ptr;
+
+                        /* Default the remove packet pointer to NULL.  */
+                        remove_packet =  NX_NULL;
+
+                        /* Determine if the packets queued has exceeded the queue
+                           depth.  */
+                        if (queued_count >= NX_ARP_MAX_QUEUE_DEPTH)
+                        {
+
+                            /* Save the packet pointer at the head of the list.  */
+                            remove_packet =  arp_ptr -> nx_arp_packets_waiting;
+
+                            /* Remove the packet from the ARP queue.  */
+                            arp_ptr -> nx_arp_packets_waiting =  remove_packet -> nx_packet_queue_next;
+
+                            /* Clear the remove packet queue next pointer.  */
+                            remove_packet -> nx_packet_queue_next =  NX_NULL;
+
+#ifndef NX_DISABLE_IP_INFO
+
+                            /* Increment the IP transmit resource error count.  */
+                            ip_ptr -> nx_ip_transmit_resource_errors++;
+
+                            /* Increment the IP send packets dropped count.  */
+                            ip_ptr -> nx_ip_send_packets_dropped++;
+#endif
+                        }
+
+                        /* Restore interrupts.  */
+                        TX_RESTORE
+
+                        /* Determine if there is a packet to remove.  */
+                        if (remove_packet)
+                        {
+
+                            /* Yes, the packet queue depth for this ARP entry was exceeded
+                               so release the packet that was removed from the queue.  */
+                            _nx_packet_transmit_release(remove_packet);
+                        }
+                    }
+                }
+                else
+                {
+
+                    /* No ARP entry was found.  We need to allocate a new ARP entry, populate it, and
+                       initiate an ARP request to get the specific physical mapping.  */
+
+                    /* Allocate a new ARP entry.  */
+                    if ((!ip_ptr -> nx_ip_arp_allocate) ||
+                        ((ip_ptr -> nx_ip_arp_allocate)(ip_ptr, &(ip_ptr -> nx_ip_arp_table[index]), NX_FALSE)))
+                    {
+
+                        /* Error, release the protection and the packet.  */
+
+#ifndef NX_DISABLE_IP_INFO
+
+                        /* Increment the IP transmit resource error count.  */
+                        ip_ptr -> nx_ip_transmit_resource_errors++;
+
+                        /* Increment the IP send packets dropped count.  */
+                        ip_ptr -> nx_ip_send_packets_dropped++;
+#endif
+
+                        /* Release the packet.  */
+                        _nx_packet_transmit_release(packet_ptr);
+
+                        /* Just return!  */
+                        return;
+                    }
+
+                    /* Otherwise, setup a pointer to the new ARP entry.  */
+                    arp_ptr =  (ip_ptr -> nx_ip_arp_table[index]) -> nx_arp_active_previous;
+
+                    /* Setup the IP address and clear the physical mapping.  */
+                    arp_ptr -> nx_arp_ip_address =            destination_ip;
+                    arp_ptr -> nx_arp_physical_address_msw =  0;
+                    arp_ptr -> nx_arp_physical_address_lsw =  0;
+                    arp_ptr -> nx_arp_entry_next_update =     NX_ARP_UPDATE_RATE;
+                    arp_ptr -> nx_arp_retries =               0;
+                    arp_ptr -> nx_arp_ip_interface =          packet_ptr -> nx_packet_address.nx_packet_interface_ptr;
+
+                    /* Ensure the queue next pointer is NULL for the packet before it
+                       is placed on the ARP waiting queue.  */
+                    packet_ptr -> nx_packet_queue_next =  NX_NULL;
+
+                    /* Add debug information. */
+                    NX_PACKET_DEBUG(NX_PACKET_ARP_WAITING_QUEUE, __LINE__, packet_ptr);
+
+                    /* Queue the packet for output.  */
+                    arp_ptr -> nx_arp_packets_waiting =  packet_ptr;
+
+                    /* Call ARP send to send an ARP request.  */
+                    (ip_ptr -> nx_ip_arp_packet_send)(ip_ptr, destination_ip, packet_ptr -> nx_packet_address.nx_packet_interface_ptr);
+                }
+
+                /* Just return!  */
+                return;
+            }
+        }
+    }
+    else
+    {
+
+        /* This IP instance does not require any IP-to-physical mapping.  */
+
+        /* Determine if we have a loopback address.  */
+        if ((((destination_ip >= NX_IP_LOOPBACK_FIRST) &&
+              (destination_ip <= NX_IP_LOOPBACK_LAST))) ||
+            (destination_ip == packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_ip_address))
+        {
+
+            /* Yes, we have an internal loopback address.  */
+            loopback = NX_TRUE;
+            driver_request.nx_ip_driver_interface = NX_NULL;
+        }
+    }
+
+    /* Check whether the packet should be loop back. */
+    if (loopback == NX_TRUE)
+    {
+
+        /* Copy the packet so it can be enqueued properly by the receive
+           processing.  */
+        if (_nx_packet_copy(packet_ptr, &packet_copy, ip_ptr -> nx_ip_default_packet_pool, NX_NO_WAIT) == NX_SUCCESS)
+        {
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+
+            /* Compute checksum for upper layer protocol. */
+            /*lint --e{644} suppress variable might not be initialized, since "packet_copy" was initialized as long as return value is NX_SUCCESS. */
+            if (packet_copy -> nx_packet_interface_capability_flag)
+            {
+                _nx_ip_packet_checksum_compute(packet_copy);
+            }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+#ifndef NX_DISABLE_IP_INFO
+
+            /* Increment the IP packet sent count.  */
+            ip_ptr -> nx_ip_total_packets_sent++;
+
+            /* Increment the IP bytes sent count.  */
+            ip_ptr -> nx_ip_total_bytes_sent +=  packet_ptr -> nx_packet_length - (ULONG)sizeof(NX_IPV4_HEADER);
+#endif
+
+#ifdef NX_IPSEC_ENABLE
+            /* Clear the ipsec sa pointer.  */
+            packet_copy -> nx_packet_ipsec_sa_ptr = NX_NULL;
+#endif /* NX_IPSEC_ENABLE  */
+
+            /* Add debug information. */
+            /*lint --e{644} suppress variable might not be initialized, since "packet_copy" was initialized as long as return value is NX_SUCCESS. */
+            NX_PACKET_DEBUG(__FILE__, __LINE__, packet_copy);
+
+            /* Send the packet to this IP's receive processing like it came in from the
+               driver.  */
+            _nx_ip_packet_deferred_receive(ip_ptr, packet_copy);
+        }
+#ifndef NX_DISABLE_IP_INFO
+        else
+        {
+
+            /* Increment the IP send packets dropped count.  */
+            ip_ptr -> nx_ip_send_packets_dropped++;
+
+            /* Increment the IP transmit resource error count.  */
+            ip_ptr -> nx_ip_transmit_resource_errors++;
+        }
+#endif
+    }
+
+    /* Check whether the packet should be sent through driver. */
+    if (driver_request.nx_ip_driver_interface)
+    {
+
+        /* Determine if fragmentation is needed.  */
+        if (packet_ptr -> nx_packet_length > packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_ip_mtu_size)
+        {
+
+#ifndef NX_DISABLE_FRAGMENTATION
+            /* Check the DF bit flag.  */
+            if ((ip_ptr -> nx_ip_fragment_processing) && (fragment != NX_DONT_FRAGMENT))
+            {
+
+                /* Fragmentation is needed, call the IP fragment processing routine.  */
+                (ip_ptr -> nx_ip_fragment_processing)(&driver_request);
+            }
+            else
+#endif /* NX_DISABLE_FRAGMENTATION */
+            {
+
+#ifndef NX_DISABLE_IP_INFO
+
+                /* Increment the IP send packets dropped count.  */
+                ip_ptr -> nx_ip_send_packets_dropped++;
+#endif
+                /* Just release the packet.  */
+                _nx_packet_transmit_release(packet_ptr);
+            }
+
+            /* In either case, this packet send is complete, just return.  */
+            return;
+        }
+
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Increment the IP packet sent count.  */
+        ip_ptr -> nx_ip_total_packets_sent++;
+
+        /* Increment the IP bytes sent count.  */
+        ip_ptr -> nx_ip_total_bytes_sent +=  packet_ptr -> nx_packet_length - (ULONG)sizeof(NX_IPV4_HEADER);
+#endif
+
+        /* If trace is enabled, insert this event into the trace buffer.  */
+        NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_PACKET_SEND, ip_ptr, packet_ptr, packet_ptr -> nx_packet_length, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
+
+        /* Add debug information. */
+        NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+        /* Driver entry must not be NULL. */
+        NX_ASSERT(packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_link_driver_entry != NX_NULL);
+
+        /* Broadcast packet.  */
+        (packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_link_driver_entry)(&driver_request);
+    }
+    else
+    {
+
+        /* Release the transmit packet.  */
+        _nx_packet_transmit_release(packet_ptr);
+    }
+}
+#endif /* !NX_DISABLE_IPV4  */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_header_add.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_header_add.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_header_add.c	(revision 69)
@@ -0,0 +1,259 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_igmp.h"
+
+#ifdef NX_IPSEC_ENABLE
+#include "nx_ipsec.h"
+#endif /* NX_IPSEC_ENABLE */
+
+#ifndef NX_DISABLE_IPV4
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_header_add                                   PORTABLE C      */
+/*                                                           6.3.0        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function prepends an IP header.                                */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to packet to send     */
+/*    source_ip                             Source IP address             */
+/*    destination_ip                        Destination IP address        */
+/*    type_of_service                       Type of service for packet    */
+/*    time_to_live                          Time to live value for packet */
+/*    protocol                              Protocol being encapsulated   */
+/*    fragment                              Don't fragment bit            */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS                            Added the header successfully */
+/*    NX_UNDERFLOW                          Invalid packet header         */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ip_checksum_compute               Compute IP checksum           */
+/*    _nx_packet_transmit_release           Release transmit packet       */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  08-02-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            supported TCP/IP offload,   */
+/*                                            resulting in version 6.1.8  */
+/*  10-31-2023     Tiejun Zhou              Modified comment(s),          */
+/*                                            supported random IP id,     */
+/*                                            resulting in version 6.3.0  */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nx_ip_header_add(NX_IP *ip_ptr, NX_PACKET *packet_ptr, ULONG source_ip, ULONG destination_ip,
+                        ULONG type_of_service, ULONG time_to_live,  ULONG protocol, ULONG fragment)
+{
+ULONG           router_alert = 0;
+NX_IPV4_HEADER *ip_header_ptr;
+ULONG           checksum;
+#if defined(NX_DISABLE_IP_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
+UINT            compute_checksum = 1;
+#endif /* defined(NX_DISABLE_IP_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
+ULONG           val;
+
+#ifdef NX_ENABLE_IP_ID_RANDOMIZATION
+    NX_PARAMETER_NOT_USED(ip_ptr);
+#endif /* NX_ENABLE_IP_ID_RANDOMIZATION */
+
+#ifndef NX_DISABLE_IGMPV2
+    /* Check IGMPv2 protocol. */
+    if ((protocol == NX_IP_IGMP) && (ip_ptr -> nx_ip_igmp_router_version == NX_IGMP_HOST_VERSION_2))
+    {
+        router_alert = 4;
+    }
+#endif
+
+    /* Prepend the IP header to the packet.  First, make room for the IP header.  */
+    packet_ptr -> nx_packet_prepend_ptr =  (packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_IPV4_HEADER)) - router_alert;
+
+    /* Increase the packet length.  */
+    packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length + (ULONG)sizeof(NX_IPV4_HEADER) + router_alert;
+
+    /* Assert prepend pointer is no less than data start pointer.  */
+    /*lint -e{946} suppress pointer subtraction, since it is necessary. */
+    NX_ASSERT(packet_ptr -> nx_packet_prepend_ptr >= packet_ptr -> nx_packet_data_start);
+
+    /* Setup the IP header pointer.  */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    ip_header_ptr =  (NX_IPV4_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
+    packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr;
+    packet_ptr -> nx_packet_ip_header_length = (UCHAR)(packet_ptr -> nx_packet_ip_header_length +
+                                                       sizeof(NX_IPV4_HEADER) + router_alert);
+
+    /* Determine if this is an identical copy for TCP retransmission.
+       RFC1122, Section3.2.1.5, Page32-33. RFC1122, Section4.2.2.15, Page90-91.  */
+    if (packet_ptr -> nx_packet_identical_copy == NX_TRUE)
+    {
+
+        /* Yes, this an identical copy for TCP retransmission.
+           The IP header has been added, return.  */
+        return(NX_SUCCESS);
+    }
+
+    /* Build the IP header.  */
+
+#ifndef NX_DISABLE_IGMPV2
+    if (router_alert)
+    {
+
+        /* Build the first 32-bit word of the IP header.  */
+        ip_header_ptr -> nx_ip_header_word_0 =  (ULONG)((NX_IP_VERSION_V4 << 28) |
+                                                        (NX_IP_HEADER_LENGTH_ENCODE_6 << 24) |
+                                                        type_of_service |
+                                                        (0xFFFF & packet_ptr -> nx_packet_length));
+    }
+    else
+#endif
+    {
+
+        /* Build the first 32-bit word of the IP header.  */
+        ip_header_ptr -> nx_ip_header_word_0 =  (NX_IP_VERSION | type_of_service | (0xFFFF & packet_ptr -> nx_packet_length));
+    }
+
+    /* Build the second 32-bit word of the IP header.  */
+#ifdef NX_ENABLE_IP_ID_RANDOMIZATION
+    ip_header_ptr -> nx_ip_header_word_1 =  (((ULONG)NX_RAND()) << NX_SHIFT_BY_16) | fragment;
+#else
+    ip_header_ptr -> nx_ip_header_word_1 =  (ip_ptr -> nx_ip_packet_id++ << NX_SHIFT_BY_16) | fragment;
+#endif /* NX_ENABLE_IP_ID_RANDOMIZATION */
+
+    /* Build the third 32-bit word of the IP header.  */
+    ip_header_ptr -> nx_ip_header_word_2 =  ((time_to_live << NX_IP_TIME_TO_LIVE_SHIFT) | protocol);
+
+    /* Place the source IP address in the IP header.  */
+    ip_header_ptr -> nx_ip_header_source_ip =  source_ip;
+
+    /* Place the destination IP address in the IP header.  */
+    ip_header_ptr -> nx_ip_header_destination_ip =  destination_ip;
+
+#ifndef NX_DISABLE_IGMPV2
+    if (router_alert)
+    {
+
+        /* Append Router Alert Option. */
+        /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        *((ULONG *)(packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER))) = (NX_IP_OPTION_COPY_FLAG |
+                                                                                      NX_IP_OPTION_CLASS |
+                                                                                      NX_IP_OPTION_ROUTER_ALERT_NUMBER |
+                                                                                      NX_IP_OPTION_ROUTER_ALERT_LENGTH |
+                                                                                      NX_IP_OPTION_ROUTER_ALERT_VALUE);
+    }
+#endif
+
+    /* Endian swapping logic.  If NX_LITTLE_ENDIAN is specified, these macros will
+       swap the endian of the IP header.  */
+    NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0);
+    NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1);
+    NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2);
+    NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip);
+    NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip);
+#ifndef NX_DISABLE_IGMPV2
+    if (router_alert)
+    {
+
+        /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        NX_CHANGE_ULONG_ENDIAN(*((ULONG *)(packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER))));
+    }
+#endif
+
+#ifdef NX_DISABLE_IP_TX_CHECKSUM
+    compute_checksum = 0;
+#endif /* NX_DISABLE_IP_TX_CHECKSUM */
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    if (packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM)
+    {
+        compute_checksum = 0;
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+#ifdef NX_IPSEC_ENABLE
+    if (packet_ptr -> nx_packet_ipsec_sa_ptr != NX_NULL)
+    {
+        if ((((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_sa_mode == NX_IPSEC_TUNNEL_MODE) &&
+            (((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_sa_encryption_method != NX_CRYPTO_NONE))
+        {
+            compute_checksum = 1;
+        }
+    }
+
+#endif /* NX_IPSEC_ENABLE */
+
+#if defined(NX_DISABLE_IP_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE)
+    if (compute_checksum)
+#endif /* defined(NX_DISABLE_IP_TX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) || defined(NX_IPSEC_ENABLE) */
+    {
+        checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4,
+                                           /* Length is the size of IP header, including options */
+                                           (UINT)(20 + router_alert),
+                                           /* IPv4 header checksum does not use src/dest addresses */
+                                           NULL, NULL);
+
+        val = (ULONG)(~checksum);
+        val = val & NX_LOWER_16_MASK;
+
+        /* Convert to network byte order. */
+        NX_CHANGE_ULONG_ENDIAN(val);
+
+        /* Now store the checksum in the IP header.  */
+        ip_header_ptr -> nx_ip_header_word_2 =  ip_header_ptr -> nx_ip_header_word_2 | val;
+    }
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    else
+    {
+        packet_ptr -> nx_packet_interface_capability_flag |= NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM;
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+    /* Return...  */
+    return(NX_SUCCESS);
+}
+
+#endif /* NX_DISABLE_IPV4 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_initialize.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_initialize.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_initialize.c	(revision 69)
@@ -0,0 +1,84 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Locate NetX IP data in this file.  */
+
+#define NX_IP_INIT
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_initialize                                   PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function initializes the various control data structures for   */
+/*    the Internet Protocol component.                                    */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_system_initialize                 System initialization         */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID  _nx_ip_initialize(VOID)
+{
+
+    /* Initialize the created IP instance variables.  */
+    _nx_ip_created_ptr =     NX_NULL;
+    _nx_ip_created_count =   0;
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_packet_deferred_receive.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_packet_deferred_receive.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_packet_deferred_receive.c	(revision 69)
@@ -0,0 +1,116 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_packet_deferred_receive                      PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function receives a packet from the link driver (usually the   */
+/*    link driver's input ISR) and places it in the deferred receive      */
+/*    packet queue.  This moves the minimal receive packet processing     */
+/*    from the ISR to the IP helper thread.                               */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to packet to send     */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    tx_event_flags_set                    Set events for IP thread      */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application I/O Driver                                              */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID  _nx_ip_packet_deferred_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+
+    /* Disable interrupts.  */
+    TX_DISABLE
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+    /* Check to see if the deferred processing queue is empty.  */
+    if (ip_ptr -> nx_ip_deferred_received_packet_head)
+    {
+
+        /* Not empty, just place the packet at the end of the queue.  */
+        (ip_ptr -> nx_ip_deferred_received_packet_tail) -> nx_packet_queue_next =  packet_ptr;
+        packet_ptr -> nx_packet_queue_next =  NX_NULL;
+        ip_ptr -> nx_ip_deferred_received_packet_tail =  packet_ptr;
+
+        /* Restore interrupts.  */
+        TX_RESTORE
+    }
+    else
+    {
+
+        /* Empty deferred receive processing queue.  Just setup the head pointers and
+           set the event flags to ensure the IP helper thread looks at the deferred processing
+           queue.  */
+        ip_ptr -> nx_ip_deferred_received_packet_head =  packet_ptr;
+        ip_ptr -> nx_ip_deferred_received_packet_tail =  packet_ptr;
+        packet_ptr -> nx_packet_queue_next =             NX_NULL;
+
+        /* Restore interrupts.  */
+        TX_RESTORE
+
+        /* Wakeup IP helper thread to process the IP deferred receive.  */
+        tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_RECEIVE_EVENT, TX_OR);
+    }
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_packet_receive.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_packet_receive.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_packet_receive.c	(revision 69)
@@ -0,0 +1,184 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_packet.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_packet_receive                               PORTABLE C      */
+/*                                                           6.1.8        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function receives a packet from the link driver (usually the   */
+/*    link driver's input ISR) and either processes it or places it in a  */
+/*    deferred processing queue, depending on the complexity of the       */
+/*    packet.                                                             */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to received packet    */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    (ipv4_packet_receive)                 Receive an IPv4 packet        */
+/*    (ipv6_packet_receive)                 Receive an IPv6 packet        */
+/*    _nx_packet_release                    Packet release                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application I/O Driver                                              */
+/*    _nx_ip_packet_send                    IP loopback packet send       */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  08-02-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            added new ip filter,        */
+/*                                            resulting in version 6.1.8  */
+/*                                                                        */
+/**************************************************************************/
+VOID  _nx_ip_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
+{
+
+UCHAR ip_version;
+UCHAR version_byte;
+
+
+#ifndef NX_DISABLE_IP_INFO
+    /* Increment the IP packet count.  */
+    ip_ptr -> nx_ip_total_packets_received++;
+#endif
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+    /* If packet_ptr -> nx_packet_interface_ptr is not set, stamp the packet with interface[0].
+       Legacy Ethernet drivers do not stamp incoming packets. */
+    if (packet_ptr -> nx_packet_address.nx_packet_interface_ptr == NX_NULL)
+    {
+        packet_ptr -> nx_packet_address.nx_packet_interface_ptr = &(ip_ptr -> nx_ip_interface[0]);
+    }
+
+    /* It's assumed that the IP link driver has positioned the top pointer in the
+       packet to the start of the IP address... so that's where we will start.  */
+    version_byte =  *(packet_ptr -> nx_packet_prepend_ptr);
+
+    /* Check the version number */
+    ip_version = (version_byte >> 4);
+
+    packet_ptr -> nx_packet_ip_version = ip_version;
+
+    packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr;
+
+#ifdef NX_ENABLE_IP_PACKET_FILTER
+    /* Check if the IP packet filter is set. */
+    if (ip_ptr -> nx_ip_packet_filter)
+    {
+
+        /* Yes, call the IP packet filter routine. */
+        if (ip_ptr -> nx_ip_packet_filter((VOID *)(packet_ptr -> nx_packet_prepend_ptr),
+                                          NX_IP_PACKET_IN) != NX_SUCCESS)
+        {
+
+            /* Drop the packet. */
+            _nx_packet_release(packet_ptr);
+            return;
+        }
+    }
+
+    /* Check if the IP packet filter extended is set. */
+    if (ip_ptr -> nx_ip_packet_filter_extended)
+    {
+
+        /* Yes, call the IP packet filter extended routine. */
+        if (ip_ptr -> nx_ip_packet_filter_extended(ip_ptr, packet_ptr, NX_IP_PACKET_IN) != NX_SUCCESS)
+        {
+
+            /* Drop the packet. */
+            _nx_packet_release(packet_ptr);
+            return;
+        }
+    }
+#endif /* NX_ENABLE_IP_PACKET_FILTER */
+
+#ifndef NX_DISABLE_IPV4
+
+    /* Process the packet according to IP version. */
+    if (ip_version == NX_IP_VERSION_V4 && ip_ptr -> nx_ipv4_packet_receive)
+    {
+
+        /* Call the IPv4 packet handler. */
+        (ip_ptr -> nx_ipv4_packet_receive)(ip_ptr, packet_ptr);
+        return;
+    }
+#endif /* !NX_DISABLE_IPV4  */
+
+#ifdef FEATURE_NX_IPV6
+    if (ip_version == NX_IP_VERSION_V6 && ip_ptr -> nx_ipv6_packet_receive)
+    {
+
+        /* Call the IPv6 packet handler. */
+        (ip_ptr -> nx_ipv6_packet_receive)(ip_ptr, packet_ptr);
+        return;
+    }
+#endif /* FEATURE_NX_IPV6 */
+
+    /* Either the ip_version number is unkonwn, or the ip_packet_receive function is
+        not defined.  In this case, the packet is reclaimed. */
+
+#ifndef NX_DISABLE_IP_INFO
+
+    /* Increment the IP invalid packet error.  */
+    ip_ptr -> nx_ip_invalid_packets++;
+
+    /* Increment the IP receive packets dropped count.  */
+    ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif
+
+    _nx_packet_release(packet_ptr);
+
+    return;
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_packet_send.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_packet_send.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_packet_send.c	(revision 69)
@@ -0,0 +1,401 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_packet.h"
+
+#ifdef NX_IPSEC_ENABLE
+#include "nx_ipsec.h"
+#endif /* NX_IPSEC_ENABLE */
+
+#ifndef NX_DISABLE_IPV4
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_packet_send                                  PORTABLE C      */
+/*                                                           6.1.8        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function prepends an IP header and sends an IP packet to the   */
+/*    appropriate link driver.                                            */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to packet to send     */
+/*    destination_ip                        Destination IP address        */
+/*    type_of_service                       Type of service for packet    */
+/*    time_to_live                          Time to live value for packet */
+/*    protocol                              Protocol being encapsulated   */
+/*    fragment                              Don't fragment bit            */
+/*    next_hop_address                      Next Hop address              */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ip_checksum_compute               Compute IP checksum           */
+/*    _nx_ip_header_add                     Add the IP header             */
+/*    _nx_ip_route_find                     Find suitable outgoing        */
+/*    _nx_ip_driver_packet_send             Send the IP packet            */
+/*    _nx_packet_transmit_release           Release transmit packet       */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  08-02-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            supported TCP/IP offload,   */
+/*                                            added new ip filter,        */
+/*                                            resulting in version 6.1.8  */
+/*                                                                        */
+/**************************************************************************/
+VOID  _nx_ip_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,
+                         ULONG destination_ip, ULONG type_of_service, ULONG time_to_live,
+                         ULONG protocol, ULONG fragment, ULONG next_hop_address)
+{
+
+#ifdef NX_IPSEC_ENABLE
+UINT            status = 0;
+ULONG           payload_size;
+USHORT          value;
+UCHAR           is_hw_processed = NX_FALSE;
+NX_IPV4_HEADER *ip_header_ptr;
+ULONG           checksum;
+ULONG           val;
+#endif /* NX_IPSEC_ENABLE */
+
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+#ifndef NX_DISABLE_IP_INFO
+
+    /* Increment the total send requests counter.  */
+    ip_ptr -> nx_ip_total_packet_send_requests++;
+#endif
+
+    /* Make sure the packet interface is set. */
+    if (packet_ptr -> nx_packet_address.nx_packet_interface_ptr == NX_NULL)
+    {
+
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Increment the IP invalid packet error.  */
+        ip_ptr -> nx_ip_invalid_transmit_packets++;
+#endif /* !NX_DISABLE_IP_INFO */
+
+        /* Prepend the IP header to the packet.  First, make room for the IP header.  */
+        packet_ptr -> nx_packet_prepend_ptr =  packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_IPV4_HEADER);
+
+        /* Increase the packet length.  */
+        packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length + (ULONG)sizeof(NX_IPV4_HEADER);
+
+        /* Release the packet.  */
+        _nx_packet_transmit_release(packet_ptr);
+
+        /* Return... nothing more can be done!  */
+        return;
+    }
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+    if (packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_capability_flag &
+        NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD)
+    {
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Increment the IP invalid packet error.  */
+        ip_ptr -> nx_ip_invalid_transmit_packets++;
+#endif
+
+        /* Ignore sending all packets for TCP/IP offload. Release the packet.  */
+        _nx_packet_transmit_release(packet_ptr);
+
+        /* Return... nothing more can be done!  */
+        return;
+    }
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+#ifdef NX_IPSEC_ENABLE
+    /* Check if this packet is continued after HW crypto engine. */
+    if (packet_ptr -> nx_packet_ipsec_sa_ptr &&
+        ((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_sa_mode == NX_IPSEC_TRANSPORT_MODE &&
+        (packet_ptr -> nx_packet_ipsec_state == NX_IPSEC_AH_PACKET ||
+         packet_ptr -> nx_packet_ipsec_state == NX_IPSEC_ESP_PACKET))
+    {
+        is_hw_processed = NX_TRUE;
+    }
+
+    /* Process this packet in IPsec transport mode? */
+    if (packet_ptr -> nx_packet_ipsec_sa_ptr &&
+        packet_ptr -> nx_packet_ipsec_state != NX_IPSEC_ESP_PACKET &&
+        packet_ptr -> nx_packet_ipsec_state != NX_IPSEC_AH_PACKET &&
+        ((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_sa_mode == NX_IPSEC_TRANSPORT_MODE)
+    {
+
+        /* Perform IPSec processing and insert IPsec headers before the IP header. */
+        /* Notice that for TCP transmission, a new packet is used to store the encrypted data, while the
+           original TCP packet is put back on to the transmitted queue. */
+        payload_size = packet_ptr -> nx_packet_length;
+        status = _nx_ipsec_ip_output_packet_process(ip_ptr, &packet_ptr, (protocol >> 16), payload_size, &payload_size);
+
+        if ((status != NX_SUCCESS) &&
+            (status != NX_IPSEC_HW_PENDING))
+        {
+
+            /* Install an area for the IP header.  This is required by the nx_packet_transmit_release. */
+            packet_ptr -> nx_packet_prepend_ptr =  packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_IPV4_HEADER);
+
+            /* Increase the packet length for the IP header.  */
+            packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length + sizeof(NX_IPV4_HEADER);
+
+            /* IPsec output packet process failed. */
+
+            /* Release the packet.  */
+            _nx_packet_transmit_release(packet_ptr);
+
+            return;
+        }
+
+        /* Now set the IPSec protocol. */
+        protocol = (ULONG)((((NX_IPSEC_SA *)packet_ptr -> nx_packet_ipsec_sa_ptr) -> nx_ipsec_sa_protocol) << 16);
+
+        /* Set the DF bit.
+           Transport mode SAs have been defined to not carry fragments (IPv4 or IPv6),RFC 4301 page 66&88..*/
+        fragment = NX_DONT_FRAGMENT;
+    }
+#endif /* NX_IPSEC_ENABLE  */
+
+
+    /* If the packet is processed by HW crypto engine, do not add IP header. */
+#ifdef NX_IPSEC_ENABLE
+    if (!is_hw_processed)
+#endif /* NX_IPSEC_ENABLE  */
+    {
+
+        /* Add the IP Header to the packet.  */
+        _nx_ip_header_add(ip_ptr, packet_ptr, packet_ptr -> nx_packet_ip_interface -> nx_interface_ip_address,
+                          destination_ip, type_of_service, time_to_live, protocol, fragment);
+
+#ifdef NX_ENABLE_IP_PACKET_FILTER
+        /* Check if the IP packet filter is set. */
+        if (ip_ptr -> nx_ip_packet_filter)
+        {
+
+            /* Yes, call the IP packet filter routine. */
+            if (ip_ptr -> nx_ip_packet_filter((VOID *)(packet_ptr -> nx_packet_prepend_ptr),
+                                              NX_IP_PACKET_OUT) != NX_SUCCESS)
+            {
+
+                /* Drop the packet. */
+                _nx_packet_transmit_release(packet_ptr);
+                return;
+            }
+        }
+
+        /* Check if the IP packet filter extended is set. */
+        if (ip_ptr -> nx_ip_packet_filter_extended)
+        {
+
+            /* Yes, call the IP packet filter extended routine. */
+            if (ip_ptr -> nx_ip_packet_filter_extended(ip_ptr, packet_ptr, NX_IP_PACKET_OUT) != NX_SUCCESS)
+            {
+
+                /* Drop the packet. */
+                _nx_packet_transmit_release(packet_ptr);
+                return;
+            }
+        }
+#endif /* NX_ENABLE_IP_PACKET_FILTER */
+    }
+
+    /* If trace is enabled, insert this event into the trace buffer.  */
+    NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IP_SEND, ip_ptr, destination_ip, packet_ptr, packet_ptr -> nx_packet_length, NX_TRACE_INTERNAL_EVENTS, 0, 0);
+
+
+#ifdef NX_IPSEC_ENABLE
+
+    if (is_hw_processed)
+    {
+
+        /* Destination IP is unknow after HW crypto engine process.  */
+        /* Get destination IP from IP header.  */
+        /* Setup the IP header pointer.  */
+        ip_header_ptr =  (NX_IPV4_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
+
+        /* Fix payload size.  */
+        value = (USHORT)(packet_ptr -> nx_packet_length);
+        NX_CHANGE_USHORT_ENDIAN(value);
+
+        /* First clear payload_size field.  */
+        ip_header_ptr -> nx_ip_header_word_0 &= 0xFFFF;
+
+        /* Fill payload_size field.  */
+        ip_header_ptr -> nx_ip_header_word_0 |= (ULONG)(value << NX_SHIFT_BY_16) & 0xFFFF0000;
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+        if (!(packet_ptr -> nx_packet_address.nx_packet_interface_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM))
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+        {
+
+            /* Clear checksum in the IP header.  */
+            ip_header_ptr -> nx_ip_header_word_2 =  ip_header_ptr -> nx_ip_header_word_2 & 0xFFFF;
+
+            checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4,
+                                               /* Length is the size of IP header, including options */
+                                               20,
+                                               /* IPv4 header checksum does not use src/dest addresses */
+                                               NULL, NULL);
+
+            val = (ULONG)(~checksum);
+            val = val & NX_LOWER_16_MASK;
+
+            /* Convert to network byte order. */
+            NX_CHANGE_ULONG_ENDIAN(val);
+
+            /* Now store the checksum in the IP header.  */
+            ip_header_ptr -> nx_ip_header_word_2 =  ip_header_ptr -> nx_ip_header_word_2 | val;
+        }
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+        else
+        {
+            packet_ptr -> nx_packet_interface_capability_flag |= NX_INTERFACE_CAPABILITY_IPV4_TX_CHECKSUM;
+        }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+    }
+
+    /* Process this packet in IPsec tunnel mode? */
+    if (packet_ptr -> nx_packet_ipsec_sa_ptr &&
+        packet_ptr -> nx_packet_ipsec_state != NX_IPSEC_ESP_PACKET &&
+        packet_ptr -> nx_packet_ipsec_state != NX_IPSEC_AH_PACKET &&
+        ((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_sa_mode == NX_IPSEC_TUNNEL_MODE)
+    {
+
+
+        /* Perform IPSec processing for tunneling. Insert IPsec headers and encapsulating the IP header. */
+        payload_size = packet_ptr -> nx_packet_length;
+        status = _nx_ipsec_ip_output_packet_process(ip_ptr, &packet_ptr, NX_PROTOCOL_IPV4, payload_size, &payload_size);
+
+        if ((status != NX_SUCCESS) &&
+            (status != NX_IPSEC_HW_PENDING))
+        {
+            /* IPsec output packet process failed. */
+
+            /* Release the packet.  */
+            _nx_packet_transmit_release(packet_ptr);
+        }
+
+        /* Tunnel consume the packet. */
+        return;
+    }
+
+    /* Process IPSec on packet requiring AH processing. */
+    if (packet_ptr -> nx_packet_ipsec_sa_ptr &&
+        packet_ptr -> nx_packet_ipsec_state == NX_IPSEC_AH_PACKET)
+    {
+
+        status = ip_ptr -> nx_ip_ipsec_authentication_header_transmit(ip_ptr, &packet_ptr, protocol, 1);
+
+        if ((status != NX_SUCCESS) &&
+            (status != NX_IPSEC_HW_PENDING))
+        {
+            /* Release the packet.  */
+            _nx_packet_transmit_release(packet_ptr);
+
+            return;
+        }
+    }
+
+    /* HW crypto driver is processing packet. */
+    if (status == NX_IPSEC_HW_PENDING)
+    {
+
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Decrement the total send requests counter.  */
+        ip_ptr -> nx_ip_total_packet_send_requests--;
+#endif
+        return;
+    }
+
+#endif
+
+    /* If the next hop address is null, indicates the specified interface is unreached.  */
+    if (next_hop_address == 0)
+    {
+
+        /* Check whether the forward feature is enabled.  */
+        if (ip_ptr -> nx_ip_forward_packet_process)
+        {
+
+            /* Initialize the interface.  */
+            packet_ptr -> nx_packet_address.nx_packet_interface_ptr = NX_NULL;
+
+            /* Figure out the best interface to send the packet on. */
+            _nx_ip_route_find(ip_ptr, destination_ip, &packet_ptr -> nx_packet_address.nx_packet_interface_ptr, &next_hop_address);
+        }
+
+        /* Make sure the packet interface and next hop address are set. */
+        /*lint -e{644} suppress variable might not be initialized, since "next_hop_address" was initialized in _nx_ip_route_find. */
+        if ((packet_ptr -> nx_packet_address.nx_packet_interface_ptr == NX_NULL) || (next_hop_address == 0))
+        {
+
+#ifndef NX_DISABLE_IP_INFO
+
+            /* Increment the IP invalid packet error.  */
+            ip_ptr -> nx_ip_invalid_transmit_packets++;
+#endif /* !NX_DISABLE_IP_INFO */
+
+            /* Release the packet.  */
+            _nx_packet_transmit_release(packet_ptr);
+
+            /* Return... nothing more can be done!  */
+            return;
+        }
+    }
+
+    /* Directly send the packet.  */
+    _nx_ip_driver_packet_send(ip_ptr, packet_ptr, destination_ip, fragment, next_hop_address);
+}
+
+#endif /* NX_DISABLE_IPV4 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_periodic_timer_entry.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_periodic_timer_entry.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_periodic_timer_entry.c	(revision 69)
@@ -0,0 +1,88 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "tx_timer.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_periodic_timer_entry                         PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function handles waking up the IP helper thread on a periodic  */
+/*    basis.  Periodic IP processing includes ARP requests, IP fragment   */
+/*    timeouts, and TCP timeouts.  All of which are driven from this      */
+/*    single periodic timer.                                              */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_address                            IP address in a ULONG         */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    tx_event_flags_set                    Set event flags to wakeup     */
+/*                                            IP helper thread            */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    ThreadX system timer thread                                         */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID  _nx_ip_periodic_timer_entry(ULONG ip_address)
+{
+
+NX_IP *ip_ptr;
+
+
+    /* Setup IP pointer.  */
+    NX_TIMER_EXTENSION_PTR_GET(ip_ptr, NX_IP, ip_address)
+
+    /* Wakeup this IP's helper thread.  */
+    tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_PERIODIC_EVENT, TX_OR);
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_route_find.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_route_find.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_route_find.c	(revision 69)
@@ -0,0 +1,363 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+
+#ifndef NX_DISABLE_IPV4
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_route_find                                   PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*     This function finds an outgoing interface and the next hop address */
+/*     for a given destination address.  The caller may also set desired  */
+/*     interface information in the ip_interface_ptr input.  For multicast*/
+/*     or limited broadcast, this routine looks for the first enabled     */
+/*     interface (link up) starting with the primary interface if         */
+/*     a hint was not set by the caller.  For directed broadcast or       */
+/*     unicast destinations, the hint is ignored and the proper outgoing  */
+/*     interface is selected.                                             */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                IN              Pointer to IP instance        */
+/*    destination_address   IN              Destination address           */
+/*    ip_interface_ptr      OUT             Interface to use, must point  */
+/*                                            to valid storage space.     */
+/*    next_hop_address      OUT             IP address for the next hop,  */
+/*                                            must point to valid storage */
+/*                                            space.                      */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS                            Operation was successful      */
+/*    NX_IP_ADDRESS_ERROR                   No suitable interface found   */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_arp_dynamic_entry_set.c           ARP entry set                 */
+/*    _nx_icmp_ping                         Transmit ICMP echo request    */
+/*    _nx_ip_packet_send                    IP packet transmit            */
+/*    _nx_tcp_client_socket_connect         TCP Client socket connection  */
+/*    _nx_udp_socket_send                   UDP packet send               */
+/*                                                                        */
+/*  NOTE:                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+ULONG  _nx_ip_route_find(NX_IP *ip_ptr, ULONG destination_address, NX_INTERFACE **ip_interface_ptr, ULONG *next_hop_address)
+{
+
+NX_INTERFACE *interface_ptr;
+ULONG         i;
+
+    /* Initialize the next hop address. */
+    *next_hop_address = 0;
+
+    /* Determine if the destination_address is multicast or directed broadcast. */
+    if (((destination_address & NX_IP_CLASS_D_MASK) == NX_IP_CLASS_D_TYPE) ||
+        (destination_address  == NX_IP_LIMITED_BROADCAST))
+    {
+
+        *next_hop_address = destination_address;
+
+        /* If the caller did not set the ip_interface value, find a link enabled 
+           interface, starting with the primary interface, for transmission.  */
+        if (*ip_interface_ptr == NX_NULL)
+        {
+
+            /* Find an interface whose link is up. */
+            for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
+            {
+
+                if (ip_ptr -> nx_ip_interface[i].nx_interface_link_up)
+                {
+                    *ip_interface_ptr = &(ip_ptr -> nx_ip_interface[i]);
+                    return(NX_SUCCESS);
+                }
+            }
+        }
+        /* If the specified interface is up, return success. */
+        else if ((*ip_interface_ptr) -> nx_interface_link_up)
+        {
+            return(NX_SUCCESS);
+        }
+
+        /* No available interface. */
+        return(NX_IP_ADDRESS_ERROR);
+    }
+
+    /* Search through the interfaces associated with the IP instance,
+       check if the the destination address is one of the local interface addresses. */
+    for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
+    {
+
+        /* Use a local variable for convenience. */
+        interface_ptr = &(ip_ptr -> nx_ip_interface[i]);
+
+        /* Check for a valid interface that maps onto the same network domain as the destination address. */
+        if ((interface_ptr -> nx_interface_valid) &&
+            (interface_ptr -> nx_interface_link_up) &&
+            (interface_ptr -> nx_interface_ip_address == destination_address) &&
+            ((*ip_interface_ptr == NX_NULL) ||
+             (*ip_interface_ptr == interface_ptr)))
+        {
+
+            /* Yes, use the entry information for interface and next hop. */
+            *ip_interface_ptr = interface_ptr;
+            *next_hop_address = destination_address;
+            return(NX_SUCCESS);
+        }
+    }
+
+#ifdef NX_ENABLE_IP_STATIC_ROUTING
+
+    /* Search through the routing table for a suitable interface. */
+    for (i = 0; i < ip_ptr -> nx_ip_routing_table_entry_count; i++)
+    {
+
+        /* Get the interface. */
+        interface_ptr = ip_ptr -> nx_ip_routing_table[i].nx_ip_routing_entry_ip_interface;
+
+        /* Skip interface that is not up. */
+        if (interface_ptr -> nx_interface_link_up == NX_FALSE)
+        {
+            continue;
+        }
+
+        /* Does this table entry match the destination table network domain?*/
+        if (ip_ptr -> nx_ip_routing_table[i].nx_ip_routing_dest_ip ==
+            (destination_address & ip_ptr -> nx_ip_routing_table[i].nx_ip_routing_net_mask))
+        {
+
+            /* Yes, is next hop address still reachable? */
+            if (interface_ptr -> nx_interface_ip_network !=
+                (ip_ptr -> nx_ip_routing_table[i].nx_ip_routing_next_hop_address &
+                 interface_ptr -> nx_interface_ip_network_mask))
+            {
+                continue;
+            }
+
+            /* Use the entry information for interface and next hop. */
+            if (*ip_interface_ptr == NX_NULL)
+            {
+                *ip_interface_ptr = interface_ptr;
+            }
+            else if (*ip_interface_ptr != interface_ptr)
+            {
+                continue;
+            }
+
+            *next_hop_address = ip_ptr -> nx_ip_routing_table[i].nx_ip_routing_next_hop_address;
+
+            return(NX_SUCCESS);
+        }
+    }
+
+#endif /* NX_ENABLE_IP_STATIC_ROUTING */
+
+    /* Search through the interfaces associated with the IP instance,
+       check if the entry exists. */
+    for (i = 0; i < NX_MAX_IP_INTERFACES; i++)
+    {
+
+        /* Use a local variable for convenience. */
+        interface_ptr = &(ip_ptr -> nx_ip_interface[i]);
+
+        /* Check for a valid interface that maps onto the same network domain as the destination address. */
+        if ((interface_ptr -> nx_interface_valid) &&
+            (interface_ptr -> nx_interface_link_up) &&
+            ((interface_ptr -> nx_interface_ip_network_mask & destination_address) == interface_ptr -> nx_interface_ip_network))
+        {
+
+            /* Yes, use the entry information for interface and next hop. */
+            if (*ip_interface_ptr == NX_NULL)
+            {
+                *ip_interface_ptr = interface_ptr;
+            }
+            /* Match loopback interface.  */
+            /* Suppress constant value, since "NX_MAX_IP_INTERFACES" can be redefined. */
+#if (NX_MAX_IP_INTERFACES == (NX_MAX_PHYSICAL_INTERFACES + 1))
+            else if (i == NX_MAX_PHYSICAL_INTERFACES)
+            {
+                *ip_interface_ptr = interface_ptr;
+            }
+#endif
+            else if (*ip_interface_ptr != interface_ptr)
+            {
+                continue;
+            }
+
+            *next_hop_address = destination_address;
+
+            return(NX_SUCCESS);
+        }
+    }
+
+    /* Search the interfaces for IPv4 Link-Local Address according to RFC3927, section2.6.  */
+    /* Determine if destination addrss is link-local address(169.254/16 Hexadecimal:0xA9FE0000).  */
+    if ((destination_address & 0xFFFF0000) == 0xA9FE0000)
+    {
+
+        /* Yes, check if the interface is set.  */
+        if (*ip_interface_ptr)
+        {
+
+            /* Determine if the interface is valid.  */
+            if (((*ip_interface_ptr) -> nx_interface_valid) &&
+                ((*ip_interface_ptr) -> nx_interface_link_up))
+            {
+
+                /* Set the next hop address.  */
+                *next_hop_address = destination_address;
+
+                return(NX_SUCCESS);
+            }
+        }
+        else
+        {
+
+            /* Search through the interfaces associated with the IP instance, set the inteface as first valid interface.  */
+            for (i = 0; i < NX_MAX_IP_INTERFACES; i++)
+            {
+
+                /* Check for a valid interface that the address is link-local address.  */
+                if ((ip_ptr -> nx_ip_interface[i].nx_interface_valid) &&
+                    (ip_ptr -> nx_ip_interface[i].nx_interface_link_up))
+                {
+
+                    /* Yes, use the entry information for interface and next hop. */
+                    *ip_interface_ptr = &(ip_ptr -> nx_ip_interface[i]);
+                    *next_hop_address = destination_address;
+
+                    return(NX_SUCCESS);
+                }
+            }
+        }
+    }
+
+    /* Does the IP instance have a gateway? */
+    if ((ip_ptr -> nx_ip_gateway_address) &&
+        (ip_ptr -> nx_ip_gateway_interface) &&
+        (ip_ptr -> nx_ip_gateway_interface -> nx_interface_link_up))
+    {
+
+        /* Get the interface. */
+        interface_ptr = ip_ptr -> nx_ip_gateway_interface;
+
+        /* Yes, is gateway address still reachable? */
+        if (interface_ptr -> nx_interface_ip_network !=
+            (ip_ptr -> nx_ip_gateway_address &
+             interface_ptr -> nx_interface_ip_network_mask))
+        {
+            return(NX_IP_ADDRESS_ERROR);
+        }
+
+        /* Use the gateway as default. */
+        if (*ip_interface_ptr == NX_NULL)
+        {
+            *ip_interface_ptr = interface_ptr;
+        }
+        else if (*ip_interface_ptr != interface_ptr)
+        {
+            return(NX_IP_ADDRESS_ERROR);
+        }
+
+        *next_hop_address = ip_ptr -> nx_ip_gateway_address;
+
+        return(NX_SUCCESS);
+    }
+
+    /* Determine if source addrss is link-local address(169.254/16 Hexadecimal:0xA9FE0000).  */
+    if (*ip_interface_ptr)
+    {
+
+        /* Determine if the interface is valid and the address of interface is link-local address.  */
+        if (((*ip_interface_ptr) -> nx_interface_valid) &&
+            ((*ip_interface_ptr) -> nx_interface_link_up) &&
+            (((*ip_interface_ptr) -> nx_interface_ip_address & 0xFFFF0000) == 0xA9FE0000))
+        {
+
+            /* Set the next hop address.  */
+            *next_hop_address = destination_address;
+
+            return(NX_SUCCESS);
+        }
+    }
+    else
+    {
+
+        /* Search through the interfaces associated with the IP instance,
+           check if interface is valid and the address of interface is link-local address. */
+        for (i = 0; i < NX_MAX_IP_INTERFACES; i++)
+        {
+
+            /* Use a local variable for convenience. */
+            interface_ptr = &(ip_ptr -> nx_ip_interface[i]);
+
+            /* Check for a valid interface that the address is link-local address.  */
+            if ((interface_ptr -> nx_interface_valid) &&
+                (interface_ptr -> nx_interface_link_up) &&
+                ((interface_ptr -> nx_interface_ip_address & 0xFFFF0000) == 0xA9FE0000))
+            {
+
+                /* Yes, use the entry information for interface and next hop. */
+                *ip_interface_ptr = interface_ptr;
+                *next_hop_address = destination_address;
+
+                return(NX_SUCCESS);
+            }
+        }
+    }
+
+    /* Cannot find a proper way to transmit this packet.
+       Return the error status. */
+    return(NX_IP_ADDRESS_ERROR);
+}
+#endif /* NX_DISABLE_IPV4 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_thread_entry.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_thread_entry.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ip_thread_entry.c	(revision 69)
@@ -0,0 +1,621 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_icmp.h"
+#include "nx_igmp.h"
+#ifdef FEATURE_NX_IPV6
+#include "nx_ipv6.h"
+#include "nx_icmpv6.h"
+#endif /* FEATURE_NX_IPV6 */
+
+#ifdef NX_IPSEC_ENABLE
+#include "nx_ipsec.h"
+#endif /* FEATURE_IPSEC_ENABLE */
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ip_thread_entry                                 PORTABLE C      */
+/*                                                           6.1.8        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function is the entry point for each IP's helper thread.  The  */
+/*    IP helper thread is responsible for periodic ARP requests,          */
+/*    reassembling fragmented IP messages, and helping with TCP           */
+/*    protocol.                                                           */
+/*                                                                        */
+/*    Note that the priority of this function is determined by the IP     */
+/*    create service.                                                     */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr_value                          Pointer to IP control block   */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Completion status             */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    tx_event_flags_get                    Suspend on event flags that   */
+/*                                            are used to signal this     */
+/*                                            thread what to do           */
+/*    tx_mutex_get                          Obtain protection mutex       */
+/*    tx_mutex_put                          Release protection mutex      */
+/*    (nx_ip_driver_deferred_packet_handler)Optional deferred packet      */
+/*                                            processing routine          */
+/*    _nx_ip_packet_receive                 IP receive packet processing  */
+/*    _nx_ipv6_multicast_join               Join IPv6 multicast group     */
+/*    (nx_arp_queue_process)                ARP receive queue processing  */
+/*    (nx_ip_arp_periodic_update)           ARP periodic update processing*/
+/*    (nx_ip_rarp_periodic_update)          RARP periodic processing      */
+/*    (nx_ip_fragment_assembly)             IP fragment processing        */
+/*    (nx_ip_fragment_timeout_check)        Fragment timeout checking     */
+/*    (nx_ip_icmp_queue_process)            ICMP message queue processing */
+/*    (nx_ip_igmp_queue_process)            IGMP message queue processing */
+/*    (nx_ip_igmp_periodic_processing)      IGMP periodic processing      */
+/*    (nx_ip_tcp_queue_process)             TCP message queue processing  */
+/*    (nx_ip_tcp_periodic_processing)       TCP periodic processing       */
+/*    (nx_tcp_deferred_cleanup_check)       TCP deferred cleanup check    */
+/*    _nx_ipsec_sa_lifetime_tick            IPsec lifetime tick update    */
+/*    (ip_link_driver)                      User supplied link driver     */
+/*    _nx_ipsec_hw_packet_process           IPsec HW packet process       */
+/*    _nx_icmpv6_send_ns                    Send Neighbor Solicitation    */
+/*                                            message                     */
+/*    (nx_nd_cache_fast_periodic_update)    ND Cache fast periodic service*/
+/*                                            routine                     */
+/*    (nx_nd_cache_slow_periodic_update)    ND Cache slow periodic service*/
+/*                                            routine                     */
+/*    _nxd_ipv6_prefix_router_timer_tick    IPv6 Preifx service routine   */
+/*    _nxd_ipv6_router_solicitation_check   IPv6 RS service routine       */
+/*    (nx_destination_table_periodic_update)                              */
+/*                                          Destination table service     */
+/*                                            routine.                    */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    ThreadX Scheduler                                                   */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  08-02-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            supported TCP/IP offload,   */
+/*                                            resulting in version 6.1.8  */
+/*                                                                        */
+/**************************************************************************/
+VOID  _nx_ip_thread_entry(ULONG ip_ptr_value)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+NX_IP_DRIVER      driver_request;
+NX_IP            *ip_ptr;
+ULONG             ip_events;
+NX_PACKET        *packet_ptr;
+UINT              i;
+UINT              index;
+ULONG             foo;
+#ifdef FEATURE_NX_IPV6
+NXD_IPV6_ADDRESS *interface_ipv6_address;
+#endif /* FEATURE_NX_IPV6 */
+
+
+    /* Setup IP pointer.  */
+    NX_THREAD_EXTENSION_PTR_GET(ip_ptr, NX_IP, ip_ptr_value)
+
+    /* Obtain the IP internal mutex before calling the driver.  */
+    tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
+
+    /* Set the IP initialization done flag to true.  */
+    ip_ptr -> nx_ip_initialize_done =  NX_TRUE;
+
+    /* Loop through all physical interfaces to initialize and enable the hardware. */
+    for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
+    {
+
+        /* Is this a valid interface with a link driver associated with it? */
+        if ((ip_ptr -> nx_ip_interface[i].nx_interface_valid) && (ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry))
+        {
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+            /* Clear capability flag first.  */
+            ip_ptr -> nx_ip_interface[i].nx_interface_capability_flag = 0;
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+
+            ip_ptr -> nx_ip_interface[i].nx_interface_link_up = NX_TRUE;
+
+            /* Yes; attach the interface to the device. */
+            driver_request.nx_ip_driver_ptr        =  ip_ptr;
+            driver_request.nx_ip_driver_command    =  NX_LINK_INTERFACE_ATTACH;
+            driver_request.nx_ip_driver_interface  = &(ip_ptr -> nx_ip_interface[i]);
+            (ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+            if (ip_ptr -> nx_ip_interface[i].nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD)
+            {
+
+                /* Set checksum capability for TCP/IP offload interface.  */
+                ip_ptr -> nx_ip_interface[i].nx_interface_capability_flag |= NX_INTERFACE_CAPABILITY_CHECKSUM_ALL;
+            }
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+            /* Call the link driver to initialize the hardware. Among other
+               responsibilities, the driver is required to provide the
+               Maximum Transfer Unit (MTU) for the physical layer. The MTU
+               should represent the actual physical layer transfer size
+               less the physical layer headers and trailers.  */
+            driver_request.nx_ip_driver_ptr =      ip_ptr;
+            driver_request.nx_ip_driver_command =  NX_LINK_INITIALIZE;
+
+            /* If trace is enabled, insert this event into the trace buffer.  */
+            NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_INITIALIZE, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
+
+            /*
+               When an IP instance is created, the first interface (nx_ip_interface[0]) is configured using parameters
+               provided in the IP create call.
+
+               When IP thread runs, it invokes the first interface link driver for link initialization.
+             */
+            (ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
+
+            /* Call the link driver again to enable the interface.  */
+            driver_request.nx_ip_driver_ptr =      ip_ptr;
+            driver_request.nx_ip_driver_command =  NX_LINK_ENABLE;
+
+            /* If trace is enabled, insert this event into the trace buffer.  */
+            NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_LINK_ENABLE, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
+
+            (ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
+
+#ifdef FEATURE_NX_IPV6
+            /* For ever IPv6 address on this interface, set the Solicitated Multicast address. */
+            interface_ipv6_address = ip_ptr -> nx_ip_interface[i].nxd_interface_ipv6_address_list_head;
+
+            while (interface_ipv6_address)
+            {
+            ULONG multicast_address[4];
+
+                SET_SOLICITED_NODE_MULTICAST_ADDRESS(multicast_address, interface_ipv6_address -> nxd_ipv6_address);
+                _nx_ipv6_multicast_join(ip_ptr, multicast_address, &ip_ptr -> nx_ip_interface[i]);
+                interface_ipv6_address = interface_ipv6_address -> nxd_ipv6_address_next;
+            }
+#ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
+            if (ip_ptr -> nx_ipv6_packet_receive)
+            {
+            ULONG address[4];
+
+                /* Create the all-node multicast group address, */
+                address[0] = 0xFF020000;
+                address[1] = 0;
+                address[2] = 0;
+                address[3] = 1;
+
+
+                /* Join all-node multicast group. */
+                _nx_ipv6_multicast_join(ip_ptr, address, &ip_ptr -> nx_ip_interface[i]);
+            }
+#endif
+#endif
+        }
+    }
+
+    /* Loop to process events for this IP instance.  */
+    for (;;)
+    {
+
+        /* Release the IP internal mutex.  */
+        tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+
+        /* Pickup IP event flags.  */
+        tx_event_flags_get(&(ip_ptr -> nx_ip_events), NX_IP_ALL_EVENTS, TX_OR_CLEAR, &ip_events, TX_WAIT_FOREVER);
+
+        /* Obtain the IP internal mutex before processing the IP event.  */
+        tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
+
+#ifdef NX_DRIVER_DEFERRED_PROCESSING
+        /* Check for any packets deferred by the Driver.  */
+        /*lint -e{644} suppress variable might not be initialized, since "ip_events" was initialized in tx_event_flags_get. */
+        if (ip_events & NX_IP_DRIVER_PACKET_EVENT)
+        {
+
+            /* Loop to process all deferred packet requests.  */
+            while (ip_ptr -> nx_ip_driver_deferred_packet_head)
+            {
+                /* Remove the first packet and process it!  */
+
+                /* Disable interrupts.  */
+                TX_DISABLE
+
+                /* Pickup the first packet.  */
+                packet_ptr =  ip_ptr -> nx_ip_driver_deferred_packet_head;
+
+                /* Move the head pointer to the next packet.  */
+                ip_ptr -> nx_ip_driver_deferred_packet_head =  packet_ptr -> nx_packet_queue_next;
+
+                /* Check for end of deferred processing queue.  */
+                if (ip_ptr -> nx_ip_driver_deferred_packet_head == NX_NULL)
+                {
+
+                    /* Yes, the queue is empty.  Set the tail pointer to NULL.  */
+                    ip_ptr -> nx_ip_driver_deferred_packet_tail =  NX_NULL;
+                }
+
+                /* Restore interrupts.  */
+                TX_RESTORE
+
+                /* Add debug information. */
+                NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+                /* make sure that there is a deferred processing function */
+                if (ip_ptr ->  nx_ip_driver_deferred_packet_handler)
+                {
+                    /* Call the actual Deferred packet processing function.  */
+                    (ip_ptr ->  nx_ip_driver_deferred_packet_handler)(ip_ptr, packet_ptr);
+                }
+            }
+
+            /* Determine if there is anything else to do in the loop.  */
+            ip_events =  ip_events & ~(NX_IP_DRIVER_PACKET_EVENT);
+            if (!ip_events)
+            {
+                continue;
+            }
+        }
+#endif
+
+        /* Check for an IP receive packet event.  */
+        /*lint -e{644} suppress variable might not be initialized, since "ip_events" was initialized by tx_event_flags_get. */
+        if (ip_events & NX_IP_RECEIVE_EVENT)
+        {
+
+            /* Loop to process all deferred packet requests.  */
+            while (ip_ptr -> nx_ip_deferred_received_packet_head)
+            {
+
+                /* Remove the first packet and process it!  */
+
+                /* Disable interrupts.  */
+                TX_DISABLE
+
+                /* Pickup the first packet.  */
+                packet_ptr =  ip_ptr -> nx_ip_deferred_received_packet_head;
+
+                /* Move the head pointer to the next packet.  */
+                ip_ptr -> nx_ip_deferred_received_packet_head =  packet_ptr -> nx_packet_queue_next;
+
+                /* Check for end of deferred processing queue.  */
+                if (ip_ptr -> nx_ip_deferred_received_packet_head == NX_NULL)
+                {
+
+                    /* Yes, the queue is empty.  Set the tail pointer to NULL.  */
+                    ip_ptr -> nx_ip_deferred_received_packet_tail =  NX_NULL;
+                }
+
+                /* Restore interrupts.  */
+                TX_RESTORE
+
+                /* Call the actual IP packet receive function.  */
+                _nx_ip_packet_receive(ip_ptr, packet_ptr);
+            }
+
+            /* Determine if there is anything else to do in the loop.  */
+            ip_events =  ip_events & ~(NX_IP_RECEIVE_EVENT);
+            if (!ip_events)
+            {
+                continue;
+            }
+        }
+
+        /* Check for a TCP message event.  */
+        if (ip_events & NX_IP_TCP_EVENT)
+        {
+
+            /* Process the TCP packet queue.  */
+            (ip_ptr -> nx_ip_tcp_queue_process)(ip_ptr);
+
+            /* Determine if there is anything else to do in the loop.  */
+            ip_events =  ip_events & ~(NX_IP_TCP_EVENT);
+            if (!ip_events)
+            {
+                continue;
+            }
+        }
+
+        /* Check for a fast TCP event.  */
+        if (ip_events & NX_IP_FAST_EVENT)
+        {
+
+            /* Start DAD for the link local address by sending off the first solicitation immediately
+               while subsequent solicitations will occur on the next slow event. */
+#ifdef FEATURE_NX_IPV6
+#ifndef NX_DISABLE_IPV6_DAD
+
+            if (ip_ptr -> nx_ip_icmpv6_packet_process)
+            {
+
+                /* Proceed with DAD check only if ICMPv6 is enabled. */
+                for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
+                {
+
+                    interface_ipv6_address = ip_ptr -> nx_ip_interface[i].nxd_interface_ipv6_address_list_head;
+
+                    if (interface_ipv6_address &&
+                        interface_ipv6_address -> nxd_ipv6_address_DupAddrDetectTransmit == NX_IPV6_DAD_TRANSMITS)
+                    {
+
+
+                        /* No. This address is still under DAD.  Transmit a NS */
+                        /* Note that the 2nd last parameter sendUnicast is set to Zero. In this case
+                           the last arg NDCacheEntry is not being used in _nx_icmpv6_send_ns. */
+                        _nx_icmpv6_send_ns(ip_ptr,
+                                           interface_ipv6_address -> nxd_ipv6_address,
+                                           0, interface_ipv6_address, 0, &ip_ptr -> nx_ipv6_nd_cache[0]);
+
+                        interface_ipv6_address -> nxd_ipv6_address_DupAddrDetectTransmit--;
+                    }
+                }
+            }
+#endif
+
+            if (ip_ptr -> nx_nd_cache_fast_periodic_update)
+            {
+                /* Run the ND Cache update routine.  This is a 100 millisecond timer */
+                ip_ptr -> nx_nd_cache_fast_periodic_update(ip_ptr);
+            }
+
+#endif /* FEATURE_NX_IPV6 */
+
+            /* Process the fast TCP processing.  */
+            if (ip_ptr -> nx_ip_tcp_fast_periodic_processing)
+            {
+                (ip_ptr -> nx_ip_tcp_fast_periodic_processing)(ip_ptr);
+            }
+
+            /* Determine if there is anything else to do in the loop.  */
+            ip_events =  ip_events & ~(NX_IP_FAST_EVENT);
+            if (!ip_events)
+            {
+                continue;
+            }
+        }
+
+        /* Check for a periodic events.  */
+        if (ip_events & NX_IP_PERIODIC_EVENT)
+        {
+
+#ifndef NX_DISABLE_IPV4
+            /* Process the ARP periodic update, if ARP has been enabled.  */
+            if (ip_ptr -> nx_ip_arp_periodic_update)
+            {
+                (ip_ptr -> nx_ip_arp_periodic_update)(ip_ptr);
+            }
+
+            /* Process the RARP periodic update, if RARP has been enabled.  */
+            if (ip_ptr -> nx_ip_rarp_periodic_update)
+            {
+                (ip_ptr -> nx_ip_rarp_periodic_update)(ip_ptr);
+            }
+
+            /* Process IGMP periodic events, if IGMP has been enabled.  */
+            if (ip_ptr -> nx_ip_igmp_periodic_processing)
+            {
+                (ip_ptr -> nx_ip_igmp_periodic_processing)(ip_ptr);
+            }
+#endif /* !NX_DISABLE_IPV4  */
+
+            /* Process IP fragmentation timeouts, if IP fragmenting has been
+               enabled.  */
+            if (ip_ptr -> nx_ip_fragment_timeout_check)
+            {
+                (ip_ptr -> nx_ip_fragment_timeout_check)(ip_ptr);
+            }
+
+            /* Process TCP periodic events, if TCP has been enabled.  */
+            if (ip_ptr -> nx_ip_tcp_periodic_processing)
+            {
+                (ip_ptr -> nx_ip_tcp_periodic_processing)(ip_ptr);
+            }
+#ifdef FEATURE_NX_IPV6
+            /* Process IPv6 events, such as DAD... */
+#ifndef NX_DISABLE_IPV6_DAD
+            if (ip_ptr -> nx_ip_icmpv6_packet_process)
+            {
+                _nx_icmpv6_perform_DAD(ip_ptr);
+            }
+#endif /* NX_DISABLE_IPV6_DAD */
+            if (ip_ptr -> nx_nd_cache_slow_periodic_update)
+            {
+                /* Run the ND Cache update routine.  This is a 1 second timer */
+                ip_ptr -> nx_nd_cache_slow_periodic_update(ip_ptr);
+            }
+
+            _nxd_ipv6_prefix_router_timer_tick(ip_ptr);
+#ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
+            _nxd_ipv6_router_solicitation_check(ip_ptr);
+#endif
+
+#ifdef NX_IPSEC_ENABLE
+            _nx_ipsec_sa_lifetime_tick(ip_ptr);
+#endif /* NX_IPSEC_ENABLE */
+
+#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
+
+            if (ip_ptr -> nx_destination_table_periodic_update)
+            {
+
+                /* Run the Destination table update routine.  This will update the timers
+                   on destination table entries' MTU data, and if expired will initiate
+                   MTU path discovery.  */
+                ip_ptr -> nx_destination_table_periodic_update(ip_ptr);
+            }
+#endif /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
+
+#endif /* FEATURE_NX_IPV6 */
+            /* Determine if there is anything else to do in the loop.  */
+            ip_events =  ip_events & ~(NX_IP_PERIODIC_EVENT);
+            if (!ip_events)
+            {
+                continue;
+            }
+        }
+
+#ifdef NX_IPSEC_ENABLE
+        if (ip_events & NX_IP_HW_DONE_EVENT)
+        {
+
+            /* Process the hw_done_packet queue.  */
+            _nx_ipsec_hw_packet_process(ip_ptr);
+        }
+#endif /* NX_IPSEC_ENABLE */
+
+#ifndef NX_DISABLE_IPV4
+        /* Check for an ARP receive packet event.  */
+        if ((ip_events & NX_IP_ARP_REC_EVENT) && (ip_ptr -> nx_ip_arp_queue_process))
+        {
+
+            /* Process the ARP queue.  */
+            (ip_ptr -> nx_ip_arp_queue_process)(ip_ptr);
+        }
+
+        /* Check for an RARP receive packet event.  */
+        if ((ip_events & NX_IP_RARP_REC_EVENT) && (ip_ptr -> nx_ip_rarp_queue_process))
+        {
+
+            /* Process the RARP queue.  */
+            (ip_ptr -> nx_ip_rarp_queue_process)(ip_ptr);
+        }
+
+        /* Check for an IGMP message event.  */
+        if (ip_events & NX_IP_IGMP_EVENT)
+        {
+
+            /* Process the ICMP packet queue.  */
+            (ip_ptr -> nx_ip_igmp_queue_process)(ip_ptr);
+        }
+
+        /* Check for an IGMP enable event.  */
+        if (ip_events & NX_IP_IGMP_ENABLE_EVENT)
+        {
+
+            /* Call the associated driver for this IP instance to register the "all hosts"
+               multicast address.  */
+            for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
+            {
+                /* Enable the hardware for IGMP for all valid interfaces. */
+                if (ip_ptr -> nx_ip_interface[i].nx_interface_valid)
+                {
+                    driver_request.nx_ip_driver_ptr =                    ip_ptr;
+                    driver_request.nx_ip_driver_command =                NX_LINK_MULTICAST_JOIN;
+                    driver_request.nx_ip_driver_physical_address_msw =   NX_IP_MULTICAST_UPPER;
+                    /*lint -e{835} -e{845} suppress operating on zero. */
+                    driver_request.nx_ip_driver_physical_address_lsw =   NX_IP_MULTICAST_LOWER | (NX_ALL_HOSTS_ADDRESS & NX_IP_MULTICAST_MASK);
+                    driver_request.nx_ip_driver_interface            =   &(ip_ptr -> nx_ip_interface[i]);
+
+                    /* If trace is enabled, insert this event into the trace buffer.  */
+                    NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_MULTICAST_JOIN, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
+
+                    (ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
+                }
+            }
+        }
+#endif /* !NX_DISABLE_IPV4  */
+
+        /* Check for an IP unfragment event.  */
+        if (ip_events & NX_IP_UNFRAG_EVENT)
+        {
+
+            /* Process the IP fragment reassemble, if fragment has been enabled.  */
+            if (ip_ptr -> nx_ip_fragment_assembly)
+            {
+                (ip_ptr -> nx_ip_fragment_assembly)(ip_ptr);
+            }
+        }
+
+#ifndef NX_DISABLE_IPV4
+        /* Check for an ICMP message event.  */
+        if (ip_events & NX_IP_ICMP_EVENT)
+        {
+
+            /* Process the ICMP packet queue.  */
+            (ip_ptr -> nx_ip_icmp_queue_process)(ip_ptr);
+        }
+#endif /* NX_DISABLE_IPV4 */
+
+        /* Check for a deferred processing request from the driver.  */
+        if (ip_events & NX_IP_DRIVER_DEFERRED_EVENT)
+        {
+
+            /* Go through each valid interface. */
+            for (index = 0; index < NX_MAX_PHYSICAL_INTERFACES; index++)
+            {
+                if (ip_ptr -> nx_ip_interface[index].nx_interface_valid)
+                {
+
+                    /* Yes, there is a deferred processing event from the driver. The only valid information
+                       fields are the IP pointer and the command.  */
+                    driver_request.nx_ip_driver_ptr =        ip_ptr;
+                    driver_request.nx_ip_driver_command =    NX_LINK_DEFERRED_PROCESSING;
+                    driver_request.nx_ip_driver_interface  = &(ip_ptr -> nx_ip_interface[index]);
+                    driver_request.nx_ip_driver_return_ptr = &foo;
+
+                    (ip_ptr -> nx_ip_interface[index].nx_interface_link_driver_entry)(&driver_request);
+                }
+            }
+        }
+
+        /* Check for a deferred TCP cleanup processing request from the driver.  */
+        if (ip_events & NX_IP_TCP_CLEANUP_DEFERRED)
+        {
+
+            /* Yes, there is a deferred cleanup processing event. Call the TCP deferred cleanup
+               processing function.  */
+            (ip_ptr -> nx_tcp_deferred_cleanup_check)(ip_ptr);
+        }
+
+        /* Check for a link status change request from the driver.  */
+        if (ip_events & NX_IP_LINK_STATUS_EVENT)
+        {
+
+            /* Yes, there is a link status change  event. Call the deferred link status processing function. */
+            _nx_ip_deferred_link_status_process(ip_ptr);
+        }
+    }
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv4_option_process.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv4_option_process.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv4_option_process.c	(revision 69)
@@ -0,0 +1,241 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_packet.h"
+#include "nx_icmpv4.h"
+
+#ifndef NX_DISABLE_IPV4
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv4_option_process                             PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function goes through IPv4 option fields.                      */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to packet to send     */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ipv4_packet_receive               Main IPv4 packet receive      */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nx_ipv4_option_process(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
+{
+
+
+NX_IPV4_HEADER *ip_header_ptr;
+UCHAR          *option_ptr;
+ULONG           ip_option_length;
+#ifndef NX_DISABLE_ICMPV4_ERROR_MESSAGE
+ULONG           ip_normal_length = 20;
+#endif /* NX_DISABLE_ICMPV4_ERROR_MESSAGE */
+UINT            index = 0;
+UCHAR           op_type;
+UCHAR           op_length;
+UCHAR           op_timestamp_offset;
+UCHAR           op_timestamp_overflow;
+UCHAR           op_timestamp_flags;
+UINT            op_timestamp_counter = 0;
+
+    /* Set the IPv4 header and IPv4 option pointer.  */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    ip_header_ptr = (NX_IPV4_HEADER *)(packet_ptr -> nx_packet_prepend_ptr);
+    option_ptr = packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER);
+
+    /* Calculate the IPv4 option length.  */
+    ip_option_length = ((((ip_header_ptr -> nx_ip_header_word_0 & NX_IP_LENGTH_MASK) >> 24) - NX_IP_NORMAL_LENGTH) & 0xFF) * (ULONG)sizeof(ULONG);
+
+    /* Loop to process the IPv4 option.  */
+    while (index < ip_option_length)
+    {
+
+        /* Get the option type.  */
+        op_type = *option_ptr;
+
+        /* Process the option type. */
+        switch (op_type)
+        {
+
+        case NX_IP_OPTION_END:
+        {
+
+            /* End option.  */
+            return(NX_TRUE);
+        }
+        case NX_IP_OPTION_NO_OPERATION:
+        {
+
+            /* No opeartion.  */
+
+            /* Update the Option pointer and index.  */
+            option_ptr++;
+            index++;
+            continue;
+        }
+        case NX_IP_OPTION_INTERNET_TIMESTAMP:
+        {
+
+            /* Timestamp option. RFC781.  */
+
+            /* Update the counter;  */
+            op_timestamp_counter++;
+
+            /* Check the counter.  */
+            if (op_timestamp_counter > 1)
+            {
+#ifndef NX_DISABLE_ICMPV4_ERROR_MESSAGE
+                /* Option length error, send a Parameter Problem Message .  */
+                /*lint -e{835} -e{845} suppress operating on zero. */
+                NX_ICMPV4_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, NX_ICMP_ZERO_CODE, (ip_normal_length + index + 2));
+#endif
+                /* Return NX_FALSE.  */
+                return(NX_FALSE);
+            }
+
+            /* Get the option length.  */
+            op_length = *(option_ptr + 1);
+
+            /* Get the option offset.  */
+            op_timestamp_offset = *(option_ptr + 2);
+
+            /* Get the option overflow and flag.  */
+            op_timestamp_overflow = (*(option_ptr + 3)) >> 4;
+            op_timestamp_flags = (*(option_ptr + 3)) & 0xF;
+
+            /* Only check the option errors.  */
+
+            /* Check the option length error.  */
+            if ((op_length < 8) || (op_length > 40) || ((op_length % 4) != 0))
+            {
+
+#ifndef NX_DISABLE_ICMPV4_ERROR_MESSAGE
+                /* Option length error, send a Parameter Problem Message .  */
+                /*lint -e{835} -e{845} suppress operating on zero. */
+                NX_ICMPV4_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, NX_ICMP_ZERO_CODE, (ip_normal_length + index + 2));
+#endif
+
+                /* Return NX_FALSE.  */
+                return(NX_FALSE);
+            }
+
+            /* Check the option offset error, offset must be greater than 5, and offset must be an odd number.  */
+            if ((op_timestamp_offset < 5) || ((op_timestamp_offset % 2) == 0))
+            {
+
+#ifndef NX_DISABLE_ICMPV4_ERROR_MESSAGE
+                /* Option offset error, send a Parameter Problem Message .  */
+                /*lint -e{835} -e{845} suppress operating on zero. */
+                NX_ICMPV4_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, NX_ICMP_ZERO_CODE, (ip_normal_length + index + 3));
+#endif
+
+                /* Return NX_FALSE.  */
+                return(NX_FALSE);
+            }
+
+            /* Check the option overflow error.  */
+            if (op_timestamp_overflow == 15)
+            {
+
+#ifndef NX_DISABLE_ICMPV4_ERROR_MESSAGE
+                /* Option overflow error, send a Parameter Problem Message .  */
+                /*lint -e{835} -e{845} suppress operating on zero. */
+                NX_ICMPV4_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, NX_ICMP_ZERO_CODE, (ip_normal_length + index + 4));
+#endif
+
+                /* Return NX_FALSE.  */
+                return(NX_FALSE);
+            }
+
+            /* Check the option flags error.  */
+            if ((op_timestamp_flags != 0) && (op_timestamp_flags != 1) && (op_timestamp_flags != 3))
+            {
+
+#ifndef NX_DISABLE_ICMPV4_ERROR_MESSAGE
+                /* Option flags error, send a Parameter Problem Message .  */
+                /*lint -e{835} -e{845} suppress operating on zero. */
+                NX_ICMPV4_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, NX_ICMP_ZERO_CODE, (ip_normal_length + index + 4));
+#endif
+
+                /* Return NX_FALSE.  */
+                return(NX_FALSE);
+            }
+            break;
+        }
+        default:
+            break;
+        }
+
+        /* Get the option length.  */
+        op_length = *(option_ptr + 1);
+
+        /* Check for invalid option length.
+           RFC 791: The option-length octet counts the option-type octet and the 
+           option-length octet as well as the option-data octets.  */
+        if ((op_length < 2) || ((index + op_length) > ip_option_length))
+        {
+            return(NX_FALSE);
+        }
+
+        /* Move to the next top level option. */
+        option_ptr += op_length;
+
+        /* Update the index.  */
+        index += op_length;
+    }
+
+    /* Return NX_TRUE.  */
+    return(NX_TRUE);
+}
+#endif /* !NX_DISABLE_IPV4  */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv4_packet_receive.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv4_packet_receive.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv4_packet_receive.c	(revision 69)
@@ -0,0 +1,781 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_igmp.h"
+#include "nx_packet.h"
+#include "nx_udp.h"
+
+#ifndef NX_DISABLE_IPV4
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv4_packet_receive                             PORTABLE C      */
+/*                                                           6.3.0        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function receives a packet from the nx_ip_packet_receive.      */
+/*    nx_ip_packet_receive forwards only IPv4 packet to this function.    */
+/*    Here it is either processes it or places it in a deferred           */
+/*    processing queue, depending on the complexity of the packet.        */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to packet to send     */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ip_checksum_compute               Compute IP checksum           */
+/*    _nx_igmp_multicast_check              Check for Multicast match     */
+/*    _nx_packet_release                    Release packet to packet pool */
+/*    tx_event_flags_set                    Set events for IP thread      */
+/*    _nx_ip_dispatch_process               The routine that examines     */
+/*                                            other optional headers and  */
+/*                                            upper layer protocols.      */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application I/O Driver                                              */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  10-31-2023     Tiejun Zhou              Modified comment(s),          */
+/*                                            validated packet length for */
+/*                                            fragments,                  */
+/*                                            resulting in version 6.3.0  */
+/*                                                                        */
+/**************************************************************************/
+VOID  _nx_ipv4_packet_receive(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
+{
+
+TX_INTERRUPT_SAVE_AREA
+#ifndef NX_DISABLE_PACKET_CHAIN
+NX_PACKET      *before_last_packet;
+NX_PACKET      *last_packet;
+#endif /* NX_DISABLE_PACKET_CHAIN */
+NX_IPV4_HEADER *ip_header_ptr;
+ULONG          *word_ptr;
+ULONG           ip_header_length;
+ULONG           protocol;
+ULONG           delta;
+ULONG           val;
+ULONG           pkt_length;
+ULONG           checksum;
+NX_INTERFACE   *if_ptr;
+NX_UDP_HEADER  *udp_header_ptr;
+UINT            dest_port;
+UINT            option_processed;
+#if defined(NX_DISABLE_IP_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY)
+UINT            compute_checksum = 1;
+#endif /* defined(NX_DISABLE_IP_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) */
+#ifdef NX_NAT_ENABLE
+UINT            packet_consumed;
+#endif
+
+#ifdef NX_DISABLE_IP_RX_CHECKSUM
+    compute_checksum = 0;
+#endif /* NX_DISABLE_IP_RX_CHECKSUM */
+
+    /* It's assumed that the IP link driver has positioned the top pointer in the
+       packet to the start of the IP address... so that's where we will start.  */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    ip_header_ptr = (NX_IPV4_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+    /* If trace is enabled, insert this event into the trace buffer.  */
+    NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IP_RECEIVE, ip_ptr, ip_header_ptr -> nx_ip_header_source_ip, packet_ptr, packet_ptr -> nx_packet_length, NX_TRACE_INTERNAL_EVENTS, 0, 0);
+
+
+    /* Pick up the first word in the IP header. */
+    val = ip_header_ptr -> nx_ip_header_word_0;
+
+    /* Convert to host byte order. */
+    NX_CHANGE_ULONG_ENDIAN(val);
+
+    /* Obtain packet length. */
+    pkt_length = val & NX_LOWER_16_MASK;
+
+    /* Make sure the IP length matches the packet length.  Some Ethernet devices
+       add padding to small packets, which results in a discrepancy between the
+       packet length and the IP header length.  */
+    if (packet_ptr -> nx_packet_length != pkt_length)
+    {
+
+        /* Determine if the packet length is less than the size reported in the IP header.  */
+        if (packet_ptr -> nx_packet_length < pkt_length)
+        {
+
+            /* Packet is too small!  */
+
+#ifndef NX_DISABLE_IP_INFO
+
+            /* Increment the IP invalid packet error.  */
+            ip_ptr -> nx_ip_invalid_packets++;
+
+            /* Increment the IP receive packets dropped count.  */
+            ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif
+
+            /* Invalid packet length, just release it.  */
+            _nx_packet_release(packet_ptr);
+
+            /* The function is complete, just return!  */
+            return;
+        }
+
+        /* Calculate the difference in the length.  */
+        delta =  packet_ptr -> nx_packet_length - pkt_length;
+
+        /* Adjust the packet length.  */
+        packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length - delta;
+
+        /* Adjust the append pointer.  */
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+        /* Loop to process adjustment that spans multiple packets.  */
+        while (delta)
+        {
+
+            /* Determine if the packet is chained (or still chained after the adjustment).  */
+            if (packet_ptr -> nx_packet_last == NX_NULL)
+            {
+
+                /* No, packet is not chained, simply adjust the append pointer in the packet.  */
+                packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_append_ptr - delta;
+
+                /* Break out of the loop, since the adjustment is complete.  */
+                break;
+            }
+
+            /* Pickup the pointer to the last packet.  */
+            last_packet =  packet_ptr -> nx_packet_last;
+
+            /* Determine if the amount to adjust is less than the payload in the last packet.  */
+            /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+            if (((ULONG)(last_packet -> nx_packet_append_ptr - last_packet -> nx_packet_prepend_ptr)) > delta)
+            {
+
+                /* Yes, simply adjust the append pointer of the last packet in the chain.  */
+                /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+                last_packet -> nx_packet_append_ptr =  last_packet -> nx_packet_append_ptr - delta;
+
+                /* Get out of the loop, since the adjustment is complete.  */
+                break;
+            }
+            else
+            {
+
+                /* Adjust the delta by the amount in the last packet.  */
+                delta =  delta - ((ULONG)(last_packet -> nx_packet_append_ptr - last_packet -> nx_packet_prepend_ptr));
+
+                /* Find the packet before the last packet.  */
+                before_last_packet =  packet_ptr;
+                while (before_last_packet -> nx_packet_next != last_packet)
+                {
+
+                    /* Move to the next packet in the chain.  */
+                    before_last_packet =  before_last_packet -> nx_packet_next;
+                }
+
+                /* At this point, we need to release the last packet and adjust the other packet
+                   pointers.  */
+
+                /* Ensure the next packet pointer is NULL in what is now the last packet.  */
+                before_last_packet -> nx_packet_next =  NX_NULL;
+
+                /* Determine if the packet is still chained.  */
+                if (packet_ptr != before_last_packet)
+                {
+
+                    /* Yes, the packet is still chained, setup the last packet pointer.  */
+                    packet_ptr -> nx_packet_last =  before_last_packet;
+                }
+                else
+                {
+
+                    /* The packet is no longer chained, set the last packet pointer to NULL.  */
+                    packet_ptr -> nx_packet_last =  NX_NULL;
+                }
+
+                /* Release the last packet.   */
+                _nx_packet_release(last_packet);
+            }
+        }
+#else
+
+        /* Simply adjust the append pointer in the packet.  */
+        packet_ptr -> nx_packet_append_ptr =  packet_ptr -> nx_packet_append_ptr - delta;
+#endif /* NX_DISABLE_PACKET_CHAIN */
+    }
+
+    /* Get the incoming interface. */
+    if_ptr = packet_ptr -> nx_packet_address.nx_packet_interface_ptr;
+
+    /* Obtain IP header length. */
+    ip_header_length =  (val & NX_IP_LENGTH_MASK) >> 24;
+
+#ifndef NX_DISABLE_RX_SIZE_CHECKING
+
+    /* Check for minimal packet length. The check is done after the endian swapping
+       since the compiler may possibly be able to optimize the lookup of
+       "nx_packet_length" and therefore reduce the amount of work performing these
+       size checks. The endian logic is okay since packets must always have
+       payloads greater than the IP header in size.  */
+    if ((packet_ptr -> nx_packet_length <= (ip_header_length << 2)) ||
+        (ip_header_length < NX_IP_NORMAL_LENGTH))
+    {
+
+        /* Packet is too small!  */
+
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Increment the IP invalid packet error.  */
+        ip_ptr -> nx_ip_invalid_packets++;
+
+        /* Increment the IP receive packets dropped count.  */
+        ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif
+
+        /* Invalid packet length, just release it.  */
+        _nx_packet_release(packet_ptr);
+
+        /* The function is complete, just return!  */
+        return;
+    }
+#endif
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+    if (if_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_IPV4_RX_CHECKSUM)
+    {
+        compute_checksum = 0;
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+#if defined(NX_DISABLE_IP_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY)
+    if (compute_checksum == 1)
+#endif /* defined(NX_DISABLE_IP_RX_CHECKSUM) || defined(NX_ENABLE_INTERFACE_CAPABILITY) */
+    {
+
+
+        checksum = _nx_ip_checksum_compute(packet_ptr, NX_IP_VERSION_V4,
+                                           /* length is the size of IP header, including options */
+                                           (UINT)(ip_header_length << 2),
+                                           /* IPv4 header checksum doesn't care src/dest addresses */
+                                           NULL, NULL);
+        checksum =  ~checksum & NX_LOWER_16_MASK;
+
+        /* Check the checksum again.  */
+        if (checksum)
+        {
+
+#ifndef NX_DISABLE_IP_INFO
+
+            /* Increment the IP invalid packet error.  */
+            ip_ptr -> nx_ip_invalid_packets++;
+
+            /* Increment the IP checksum error.  */
+            ip_ptr -> nx_ip_receive_checksum_errors++;
+
+            /* Increment the IP receive packets dropped count.  */
+            ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif
+
+            /* Checksum error, just release it.  */
+            _nx_packet_release(packet_ptr);
+
+            /* The function is complete, just return!  */
+            return;
+        }
+    }
+
+    /* IP receive checksum processing is disabled... just check for and remove if
+       necessary the IP option words.  */
+
+    /* Endian swapping logic.  If NX_LITTLE_ENDIAN is specified, these macros will
+       swap the endian of the IP header.  */
+    NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0);
+    NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1);
+    NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_2);
+    NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip);
+    NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip);
+
+#ifdef NX_ENABLE_SOURCE_ADDRESS_CHECK
+    /* Check whether source address is valid. */
+    /* Section 3.2.1.3, page 30, RFC 1122. */
+    if (if_ptr -> nx_interface_address_mapping_needed == NX_TRUE)
+    {
+        if (((ip_header_ptr -> nx_ip_header_source_ip & ~(if_ptr -> nx_interface_ip_network_mask)) == ~(if_ptr -> nx_interface_ip_network_mask)) ||
+            (((ip_header_ptr -> nx_ip_header_source_ip & ~(if_ptr -> nx_interface_ip_network_mask)) == 0) &&
+             (ip_header_ptr -> nx_ip_header_source_ip != 0)) ||
+            ((ip_header_ptr -> nx_ip_header_source_ip & NX_IP_CLASS_D_MASK) == NX_IP_CLASS_D_TYPE))
+        {
+
+#ifndef NX_DISABLE_IP_INFO
+
+            /* Increment the IP invalid address error.  */
+            ip_ptr -> nx_ip_invalid_receive_address++;
+
+            /* Increment the IP receive packets dropped count.  */
+            ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif
+
+            /* Toss the IP packet since we don't know what to do with it!  */
+            _nx_packet_release(packet_ptr);
+
+            /* Return to caller.  */
+            return;
+        }
+    }
+#endif /* NX_ENABLE_SOURCE_ADDRESS_CHECK */
+
+    /* Determine if there are options in the IP header that make the length greater
+       than the default length.  */
+    if (ip_header_length > NX_IP_NORMAL_LENGTH)
+    {
+
+        /* Process the IPv4 option.  */
+        option_processed = _nx_ipv4_option_process(ip_ptr, packet_ptr);
+
+        /* Check the status.  */
+        if (option_processed == NX_FALSE)
+        {
+
+#ifndef NX_DISABLE_IP_INFO
+
+            /* Increment the IP receive packets dropped count.  */
+            ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif
+
+            /* IPv4 option error, toss the packet!  */
+            _nx_packet_release(packet_ptr);
+
+            /* In all cases, receive processing is finished.  Return to caller.  */
+            return;
+        }
+
+        /* Setup a pointer to the last option word.  */
+        word_ptr = ((ULONG *)((VOID *)ip_header_ptr)) + ip_header_length - 1;
+
+        /* Remove the option words prior to handling the IP header.  */
+        *word_ptr-- = ip_header_ptr -> nx_ip_header_destination_ip;
+        *word_ptr-- = ip_header_ptr -> nx_ip_header_source_ip;
+        *word_ptr-- = ip_header_ptr -> nx_ip_header_word_2;
+        *word_ptr-- = ip_header_ptr -> nx_ip_header_word_1;
+        *word_ptr = (ULONG)(((ip_header_ptr -> nx_ip_header_word_0) & (~NX_IP_LENGTH_MASK)) | NX_IP_VERSION);
+
+        /* Update the ip_header_ptr and the packet and the packet prepend pointer, ip header pointer and length.  */
+        /*lint -e{929} -e{740} -e{826} suppress cast from pointer to pointer, since it is necessary  */
+        ip_header_ptr =  (NX_IPV4_HEADER *)word_ptr;
+
+        /*lint -e{928} suppress cast from pointer to pointer, since it is necessary  */
+        packet_ptr -> nx_packet_prepend_ptr = (UCHAR *)word_ptr;
+        packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr;
+        packet_ptr -> nx_packet_length = packet_ptr -> nx_packet_length - ((ip_header_length -  NX_IP_NORMAL_LENGTH) * (ULONG)sizeof(ULONG));
+    }
+
+    /* Check if this IP interface has a NAT forwarding service.  If so, let NAT get the
+       packet first and if it is not a packet that should be forwarded by NAT, then
+       let NetX process the packet in the normal way.  */
+
+#ifdef NX_NAT_ENABLE
+    /* Check if this IP interface has a NAT forwarding service. */
+    if (ip_ptr -> nx_ip_nat_packet_process)
+    {
+
+        /* Call NAT preprocess hanlder to check if NAT module can process this packet.  */
+        if ((ip_ptr -> nx_ip_nat_packet_process)(ip_ptr, packet_ptr, NX_FALSE) == NX_TRUE)
+        {
+
+            /* NAT router would need to assemble the fragments together first
+               and then translate prior to forwarding. RFC2663, RFC2766. */
+
+            /* Determine if this packet is fragmented.  If so, place it on the deferred processing
+               queue. The input packet will then be processed by an IP system thread.  */
+            if (ip_header_ptr -> nx_ip_header_word_1 & NX_IP_FRAGMENT_MASK)
+            {
+
+#ifndef NX_DISABLE_IP_INFO
+
+                /* Increment the IP receive fragments count.  */
+                ip_ptr -> nx_ip_total_fragments_received++;
+#endif
+
+                /* Yes, the incoming IP header is fragmented.  Check to see if IP fragmenting
+                   has been enabled.  */
+                if (ip_ptr -> nx_ip_fragment_assembly)
+                {
+
+                    /* Yes, fragmenting is available.  Place the packet on the incoming
+                       fragment queue.  */
+
+                    /* Disable interrupts.  */
+                    TX_DISABLE
+
+                    /* Determine if the queue is empty.  */
+                    if (ip_ptr -> nx_ip_received_fragment_head)
+                    {
+
+                        /* Reassembly queue is not empty, add this packet to the end of
+                           the queue.  */
+                        (ip_ptr -> nx_ip_received_fragment_tail) -> nx_packet_queue_next =  packet_ptr;
+                        packet_ptr -> nx_packet_queue_next =  NX_NULL;
+                        ip_ptr -> nx_ip_received_fragment_tail =  packet_ptr;
+                    }
+                    else
+                    {
+
+                        /* Reassembly queue is empty.  Just setup the head and tail pointers
+                           to point to this packet.  */
+                        ip_ptr -> nx_ip_received_fragment_head =  packet_ptr;
+                        ip_ptr -> nx_ip_received_fragment_tail =  packet_ptr;
+                        packet_ptr -> nx_packet_queue_next =      NX_NULL;
+                    }
+
+                    /* Add debug information. */
+                    NX_PACKET_DEBUG(NX_PACKET_IP_FRAGMENT_QUEUE, __LINE__, packet_ptr);
+
+                    /* Restore interrupts.  */
+                    TX_RESTORE
+
+#ifndef NX_FRAGMENT_IMMEDIATE_ASSEMBLY
+                    /* Wakeup IP helper thread to process the IP fragment re-assembly.  */
+                    tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_UNFRAG_EVENT, TX_OR);
+#else
+                    /* Process the IP fragment reassemble.  */
+                    (ip_ptr -> nx_ip_fragment_assembly)(ip_ptr);
+#endif /* NX_FRAGMENT_IMMEDIATE_ASSEMBLY */
+                }
+                else
+                {
+
+#ifndef NX_DISABLE_IP_INFO
+
+                    /* Increment the IP receive packets dropped count.  */
+                    ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif
+
+                    /* Fragmentation has not been enabled, toss the packet!  */
+                    _nx_packet_release(packet_ptr);
+                }
+
+                /* In all cases, receive processing is finished.  Return to caller.  */
+                return;
+            }
+
+            /* Normal packet, so forward this packet to the NAT handler. If NAT does not 'consume' this
+               packet, allow NetX to process the packet.  */
+            packet_consumed = (ip_ptr -> nx_ip_nat_packet_process)(ip_ptr, packet_ptr, NX_TRUE);
+
+            /* Check to see if the packet has been consumed by NAT.  */
+            if (packet_consumed)
+            {
+
+#ifndef NX_DISABLE_IP_INFO
+
+                /* Increment the IP packets forwarded counter.  */
+                ip_ptr -> nx_ip_packets_forwarded++;
+#endif /* NX_DISABLE_IP_INFO */
+
+                return;
+            }
+        }
+
+        /* (NetX will process all packets that drop through here.) */
+    }
+#endif
+
+    /* Determine if the IP datagram is for this IP address or a broadcast IP on this
+       network.  */
+    if ((ip_header_ptr -> nx_ip_header_destination_ip == if_ptr -> nx_interface_ip_address) ||
+
+        /* Check for incoming IP address of zero.  Incoming IP address of zero should
+           be received regardless of our current IP address.  */
+        (ip_header_ptr -> nx_ip_header_destination_ip == 0) ||
+
+        /* Check for IP broadcast.  */
+        (((ip_header_ptr -> nx_ip_header_destination_ip & if_ptr -> nx_interface_ip_network_mask) ==
+          if_ptr -> nx_interface_ip_network) &&
+         ((ip_header_ptr -> nx_ip_header_destination_ip & ~(if_ptr -> nx_interface_ip_network_mask)) ==
+          ~(if_ptr -> nx_interface_ip_network_mask))) ||
+
+        /* Check for limited broadcast.  */
+        (ip_header_ptr -> nx_ip_header_destination_ip == NX_IP_LIMITED_BROADCAST) ||
+
+        /* Check for loopback address.  */
+        ((ip_header_ptr -> nx_ip_header_destination_ip >= NX_IP_LOOPBACK_FIRST) &&
+         (ip_header_ptr -> nx_ip_header_destination_ip <= NX_IP_LOOPBACK_LAST)) ||
+
+        /* Check for valid Multicast address.  */
+        (_nx_igmp_multicast_check(ip_ptr, ip_header_ptr -> nx_ip_header_destination_ip, if_ptr)))
+    {
+
+        /* Determine if this packet is fragmented.  If so, place it on the deferred processing
+           queue.  The input packet will then be processed by an IP system thread.  */
+        if (ip_header_ptr -> nx_ip_header_word_1 & NX_IP_FRAGMENT_MASK)
+        {
+
+#ifndef NX_DISABLE_IP_INFO
+
+            /* Increment the IP receive fragments count.  */
+            ip_ptr -> nx_ip_total_fragments_received++;
+#endif
+
+            /* Yes, the incoming IP header is fragmented.  Check to see if IP fragmenting
+               has been enabled.  */
+#ifdef NX_ENABLE_LOW_WATERMARK
+            if (ip_ptr -> nx_ip_fragment_assembly &&
+                (packet_ptr -> nx_packet_pool_owner -> nx_packet_pool_available >=
+                 packet_ptr -> nx_packet_pool_owner -> nx_packet_pool_low_watermark))
+#else
+            if (ip_ptr -> nx_ip_fragment_assembly)
+#endif
+            {
+
+                /* Yes, fragmenting is available.  Place the packet on the incoming
+                   fragment queue.  */
+
+                /* Check packet length with more fragment bit. If not multiple of 8 bytes...  */
+                if ((ip_header_ptr -> nx_ip_header_word_1 & NX_IP_MORE_FRAGMENT) &&
+                    (((pkt_length  - (ULONG)sizeof(NX_IPV4_HEADER))  & 0x7) != 0))
+                {
+
+                    /* Invalid length.  Drop the packet.  */
+#ifndef NX_DISABLE_IP_INFO
+
+                    /* Increment the IP receive packets dropped count.  */
+                    ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif
+                    _nx_packet_release(packet_ptr);
+                    return;
+                }
+
+                /* Disable interrupts.  */
+                TX_DISABLE
+
+                /* Determine if the queue is empty.  */
+                if (ip_ptr -> nx_ip_received_fragment_head)
+                {
+
+                    /* Reassembly queue is not empty, add this packet to the end of
+                       the queue.  */
+                    (ip_ptr -> nx_ip_received_fragment_tail) -> nx_packet_queue_next =  packet_ptr;
+                    packet_ptr -> nx_packet_queue_next =  NX_NULL;
+                    ip_ptr -> nx_ip_received_fragment_tail =  packet_ptr;
+                }
+                else
+                {
+
+                    /* Reassembly queue is empty.  Just setup the head and tail pointers
+                       to point to this packet.  */
+                    ip_ptr -> nx_ip_received_fragment_head =  packet_ptr;
+                    ip_ptr -> nx_ip_received_fragment_tail =  packet_ptr;
+                    packet_ptr -> nx_packet_queue_next =      NX_NULL;
+                }
+
+                /* Add debug information. */
+                NX_PACKET_DEBUG(NX_PACKET_IP_FRAGMENT_QUEUE, __LINE__, packet_ptr);
+
+                /* Restore interrupts.  */
+                TX_RESTORE
+
+#ifndef NX_FRAGMENT_IMMEDIATE_ASSEMBLY
+                /* Wakeup IP helper thread to process the IP fragment re-assembly.  */
+                tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_UNFRAG_EVENT, TX_OR);
+#else
+                /* Process the IP fragment reassemble.  */
+                (ip_ptr -> nx_ip_fragment_assembly)(ip_ptr);
+#endif /* NX_FRAGMENT_IMMEDIATE_ASSEMBLY */
+            }
+            else
+            {
+
+#ifndef NX_DISABLE_IP_INFO
+
+                /* Increment the IP receive packets dropped count.  */
+                ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif
+
+                /* Fragmentation has not been enabled, toss the packet!  */
+                _nx_packet_release(packet_ptr);
+            }
+
+            /* In all cases, receive processing is finished.  Return to caller.  */
+            return;
+        }
+
+        /* Determine what protocol the current IP datagram is.  */
+        protocol =  (ip_header_ptr -> nx_ip_header_word_2 >> 16) & 0xFF;
+
+        /* Remove the IP header from the packet.  */
+        packet_ptr -> nx_packet_prepend_ptr =  packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER);
+
+        /* Adjust the length.  */
+        packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length - (ULONG)sizeof(NX_IPV4_HEADER);
+
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Increment the number of packets delivered.  */
+        ip_ptr -> nx_ip_total_packets_delivered++;
+
+        /* Increment the IP packet bytes received (not including the header).  */
+        ip_ptr -> nx_ip_total_bytes_received +=  packet_ptr -> nx_packet_length;
+#endif
+        if (_nx_ip_dispatch_process(ip_ptr, packet_ptr, (UINT)protocol))
+        {
+            _nx_packet_release(packet_ptr);
+        }
+    }
+    /* Try to receive the DHCP message before release this packet.
+       NetX should receive the unicast DHCP message when interface IP address is zero.  */
+
+    /* Check if this IP interface has IP address.  */
+    else if (if_ptr -> nx_interface_ip_address == 0)
+    {
+
+        /* Determine what protocol the current IP datagram is.  */
+        protocol =  ip_header_ptr -> nx_ip_header_word_2 & NX_IP_PROTOCOL_MASK;
+
+        /* Check if this packet is UDP message.  */
+        if (protocol == NX_IP_UDP)
+        {
+
+            /* Remove the IP header from the packet.  */
+            packet_ptr -> nx_packet_prepend_ptr =  packet_ptr -> nx_packet_prepend_ptr + sizeof(NX_IPV4_HEADER);
+
+            /* Adjust the length.  */
+            packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length - (ULONG)sizeof(NX_IPV4_HEADER);
+
+#ifndef NX_DISABLE_IP_INFO
+
+            /* Increment the number of packets delivered.  */
+            ip_ptr -> nx_ip_total_packets_delivered++;
+
+            /* Increment the IP packet bytes received (not including the header).  */
+            ip_ptr -> nx_ip_total_bytes_received +=  packet_ptr -> nx_packet_length;
+#endif
+
+            /* Pickup the pointer to the head of the UDP packet.  */
+            /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+            udp_header_ptr =  (NX_UDP_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
+
+            /* Endian swapping logic.  If NX_LITTLE_ENDIAN is specified, these macros will
+               swap the endian of the UDP header.  */
+            NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0);
+
+            /* Pickup the destination UDP port.  */
+            dest_port =  (UINT)(udp_header_ptr -> nx_udp_header_word_0 & NX_LOWER_16_MASK);
+
+            /* Endian swapping logic.  If NX_LITTLE_ENDIAN is specified, these macros will
+               swap the endian of the UDP header.  */
+            NX_CHANGE_ULONG_ENDIAN(udp_header_ptr -> nx_udp_header_word_0);
+
+            /* Check if this packet is DHCP message.  */
+            if (dest_port == 68)
+            {
+                if (ip_ptr -> nx_ip_udp_packet_receive)
+                {
+
+                    /* Yes, dispatch it to the appropriate UDP handler if present.  */
+                    (ip_ptr -> nx_ip_udp_packet_receive)(ip_ptr, packet_ptr);
+
+                    return;
+                }
+            }
+        }
+
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Decrement the number of packets delivered.  */
+        ip_ptr -> nx_ip_total_packets_delivered--;
+
+        /* Decrement the IP packet bytes received (not including the header).  */
+        ip_ptr -> nx_ip_total_bytes_received -=  packet_ptr -> nx_packet_length;
+
+        /* Increment the IP invalid address error.  */
+        ip_ptr -> nx_ip_invalid_receive_address++;
+
+        /* Increment the IP receive packets dropped count.  */
+        ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif
+
+        /* Toss the IP packet since we don't know what to do with it!  */
+        _nx_packet_release(packet_ptr);
+
+        /* Return to caller.  */
+        return;
+    }
+    else if (ip_ptr -> nx_ip_forward_packet_process)
+    {
+
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Increment the IP packets forwarded counter.  */
+        ip_ptr -> nx_ip_packets_forwarded++;
+#endif
+
+        /* The packet is not for this IP instance so call the
+           forward IP packet processing routine.  */
+        (ip_ptr -> nx_ip_forward_packet_process)(ip_ptr, packet_ptr);
+    }
+    else
+    {
+
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Increment the IP invalid address error.  */
+        ip_ptr -> nx_ip_invalid_receive_address++;
+
+        /* Increment the IP receive packets dropped count.  */
+        ip_ptr -> nx_ip_receive_packets_dropped++;
+#endif
+
+        /* Toss the IP packet since we don't know what to do with it!  */
+        _nx_packet_release(packet_ptr);
+
+        /* Return to caller.  */
+        return;
+    }
+}
+#endif /* !NX_DISABLE_IPV4  */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_fragment_process.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_fragment_process.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_fragment_process.c	(revision 69)
@@ -0,0 +1,428 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol version 6 (IPv6)                                  */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "tx_api.h"
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_ipv6.h"
+#include "nx_packet.h"
+
+#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
+#include "nx_icmpv6.h"
+#endif
+
+#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_FRAGMENTATION)
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_fragment_process                           PORTABLE C      */
+/*                                                           6.3.0        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function breaks the supplied packet into fragments and sends   */
+/*    them out through the associated IP driver.  This function uses the  */
+/*    already built IP header and driver request structure for each       */
+/*    packet fragment.                                                    */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    driver_req_ptr                        Pointer to driver request     */
+/*    mtu                                   Maximum transfer unit         */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ip_packet_checksum_compute        Compute checksum              */
+/*    _nx_packet_allocate                   Allocate packet               */
+/*    _nx_ipv6_packet_copy                  Copy packet                   */
+/*    _nx_packet_release                    Release packet                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_icmpv6_send_queued_packets                                      */
+/*    _nx_ipv6_packet_send                                                */
+/*                                                                        */
+/*  NOTE                                                                  */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  10-31-2023     Tiejun Zhou              Modified comment(s),          */
+/*                                            supported random IP id,     */
+/*                                            resulting in version 6.3.0  */
+/*                                                                        */
+/**************************************************************************/
+VOID _nx_ipv6_fragment_process(struct NX_IP_DRIVER_STRUCT *driver_req_ptr, UINT mtu)
+{
+
+NX_PACKET                      *first_fragment, *source_packet, *previous_packet;
+UCHAR                          *fragmentable_ptr, *last_header_location;
+UINT                            packet_length, unfragmentable_size;
+ULONG                           packet_id;
+NX_IP_DRIVER                    driver_request;
+NX_IP                          *ip_ptr;
+UCHAR                           next_header;
+UCHAR                           hdr_ext_len;
+UINT                            fragment_offset = 0;
+INT                             error = 0;
+NX_IPV6_HEADER_FRAGMENT_OPTION *fragment_option;
+INT                             last_fragment = 0;
+NX_IPV6_HEADER                 *ipv6_header;
+ULONG                           word_1;
+ULONG                           val;
+NX_PACKET_POOL                 *pool_ptr;
+
+
+    first_fragment = NX_NULL;
+
+    /* Setup the local driver request packet that will be used for each
+       fragment.  There will be a unique packet pointer for each request, but
+       otherwise all the other fields will remain constant.  */
+    driver_request = *driver_req_ptr;
+
+    /* Setup the IP pointer. */
+    ip_ptr = driver_req_ptr -> nx_ip_driver_ptr;
+
+#ifndef NX_DISABLE_IP_INFO
+
+    /* Increment the total number of fragment requests.  */
+    ip_ptr -> nx_ip_total_fragment_requests++;
+#endif
+
+    /* Source_packet points a packet (or a chain of packets) that already has IP header
+       constructed.  The prepend pointer should point to the IPv6 header. */
+#ifdef NX_ENABLE_IP_ID_RANDOMIZATION
+    packet_id = (ULONG)NX_RAND();
+#else
+    packet_id = ip_ptr -> nx_ip_packet_id++;
+#endif /* NX_ENABLE_IP_ID_RANDOMIZATION */
+
+    /* Byte swap packet_id */
+    NX_CHANGE_ULONG_ENDIAN(packet_id);
+
+    /* Pickup the source packet pointer.  */
+    source_packet = driver_req_ptr -> nx_ip_driver_packet;
+    source_packet -> nx_packet_last = source_packet;
+    source_packet -> nx_packet_ip_header = source_packet -> nx_packet_prepend_ptr;
+    pool_ptr = source_packet -> nx_packet_pool_owner;
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, source_packet);
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+
+    /* Compute checksum for upper layer protocol. */
+    if (source_packet -> nx_packet_interface_capability_flag)
+    {
+        _nx_ip_packet_checksum_compute(source_packet);
+    }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+    /* Find out the unfragmentable part. */
+    fragmentable_ptr = source_packet -> nx_packet_prepend_ptr + sizeof(NX_IPV6_HEADER);
+    last_header_location  = (source_packet -> nx_packet_prepend_ptr + 6);
+    next_header = *last_header_location;
+
+#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
+
+    /* RFC 1981 Section 4 requires that we include a fragment header if we received a
+       packet from a host with an MTU less than the minimum required path MTU, regardless
+       if we decide to fragment the packet (which we aren't). */
+    if (mtu < NX_MINIMUM_IPV6_PATH_MTU)
+    {
+
+        /* So reset the mtu to the minimum packet size. */
+        mtu = NX_MINIMUM_IPV6_PATH_MTU;
+    }
+
+#endif
+
+    /* Fragment Option header appears after Hop-by-hop and routing headers.  So we need
+       to skip these headers if they are present. */
+    while ((next_header == NX_PROTOCOL_NEXT_HEADER_HOP_BY_HOP) ||
+           (next_header == NX_PROTOCOL_NEXT_HEADER_ROUTING))
+    {
+
+        /* Move to the next header */
+        hdr_ext_len = *(fragmentable_ptr + 1);
+
+        last_header_location = fragmentable_ptr;
+
+        next_header = *fragmentable_ptr;
+
+        /*lint -e{923} suppress cast between pointer and UINT.  */
+        fragmentable_ptr = NX_UCHAR_POINTER_ADD(fragmentable_ptr, ((hdr_ext_len + 1) << 3));
+    }
+
+    /* If hdr_ext_len == 0, there are no optional headers in the unfragmentable region. */
+    *last_header_location = NX_PROTOCOL_NEXT_HEADER_FRAGMENT;
+
+    /* Change the very last "next_header" to
+       compute the unfragmentable size which includes MAC header, IPv6 header,
+       and any unfragmentable header, but not the fragment header option. */
+    /*lint -e{923} suppress cast between pointer and UINT.  */
+    unfragmentable_size = (UINT)((ALIGN_TYPE)fragmentable_ptr - (ALIGN_TYPE)source_packet -> nx_packet_prepend_ptr);
+
+    /* Compute the fragmentable size. */
+    packet_length = (UINT)(source_packet -> nx_packet_length - unfragmentable_size);
+
+    /* Add the size of the fragment option header.
+       This number is going to be used for finding the starting position of
+       the fragmentable part. */
+    /* unfragmentable_size += sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION);*/
+
+    /* Now fragmentable_ptr points to the begining of fragmentable part of 'remaining_pkt' */
+    /* Also packet_prepend_ptr points to the data (fragmentable) area.  */
+
+    /* The fragmentable pointer starts from the first packet.*/
+    while (packet_length)
+    {
+
+    NX_PACKET *new_packet;
+    UINT       fragment_size;
+    UINT       remaining_bytes;
+    UINT       nx_packet_size;
+
+        /*
+           Determine the fragment size. Take the MTU size, minus the unfragmentable
+           portion, and round down to multiple of 8-bytes, then add the unfragmentable
+           portion back.   This is the size of each fragment, excluding the last fragment.
+         */
+        fragment_size = (mtu - unfragmentable_size) & 0xFFF8;
+        fragment_size -= (ULONG)sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION);
+
+        if (fragment_size >= packet_length)
+        {
+            fragment_size = packet_length;
+            last_fragment = 1;
+        }
+
+        /* Compute the remaining packet length */
+        packet_length -= fragment_size;
+
+        /* Figure out the number of bytes (fragmentable part + unfragmentable part)
+           of this frame. */
+        remaining_bytes = fragment_size + unfragmentable_size + (UINT)sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION) + NX_PHYSICAL_HEADER;
+
+        /* find the size of each nx packet. */
+        nx_packet_size = (UINT)((pool_ptr -> nx_packet_pool_payload_size) & 0xFFFC);
+
+        if (nx_packet_size > (mtu + NX_PHYSICAL_HEADER))
+        {
+            nx_packet_size = (mtu + NX_PHYSICAL_HEADER);
+        }
+
+        /* Make sure we have enough packets for this fragment. */
+        do
+        {
+
+            /* Allocate a packet from the default packet pool.  */
+            if (_nx_packet_allocate(pool_ptr, &new_packet,
+                                    0, TX_NO_WAIT))
+            {
+                error = 1;
+                break;
+            }
+
+            /* Add debug information. */
+            NX_PACKET_DEBUG(__FILE__, __LINE__, new_packet);
+
+            /*lint -e{644} suppress variable might not be initialized, since "new_packet" was initialized in _nx_packet_allocate. */
+            new_packet -> nx_packet_ip_version = NX_IP_VERSION_V6;
+
+            if (first_fragment == NX_NULL)
+            {
+                first_fragment = new_packet;
+                first_fragment -> nx_packet_last = new_packet;
+
+                /* first_fragment -> nx_packet_length = fragment_size + unfragmentable_size. */
+                /* May need to configure additional header information. */
+            }
+            else
+            {
+                first_fragment -> nx_packet_last -> nx_packet_next = new_packet;
+                first_fragment -> nx_packet_last = new_packet;
+            }
+            /* Establish the "usable" size of the packet.
+               The actual copy routine uses this information to figure out how many
+               bytes to transer to the fragmented packets.*/
+
+            /* The true packet size is set in the first packet. */
+            if (nx_packet_size > remaining_bytes)
+            {
+                /* This is going to be the last packet we need. */
+                new_packet -> nx_packet_length = remaining_bytes;
+                remaining_bytes = 0;
+            }
+            else
+            {
+                new_packet -> nx_packet_length = nx_packet_size;
+                remaining_bytes -= nx_packet_size;
+            }
+        } while (remaining_bytes);
+
+        if (error)
+        {
+            break;
+        }
+
+        /* We have all the packets ready.  Need to copy data. */
+
+        /* First step:  copy the unfragmentable part. */
+        /* Save the state from last iteration. */
+        previous_packet = source_packet -> nx_packet_last;
+
+        source_packet -> nx_packet_last = source_packet;
+        source_packet -> nx_packet_prepend_ptr = source_packet -> nx_packet_ip_header;
+
+        first_fragment -> nx_packet_last = first_fragment;
+
+        first_fragment -> nx_packet_prepend_ptr += NX_PHYSICAL_HEADER;
+        first_fragment -> nx_packet_append_ptr += NX_PHYSICAL_HEADER;
+
+        /* For the first packet, the prepend pointer is already at the begining of the IP header. */
+        if (_nx_ipv6_packet_copy(source_packet, first_fragment, unfragmentable_size))
+        {
+            break;
+        }
+
+        /* Fill in the fragment header area.  Be careful here: we assume the unfragmentable part does not
+           span over multiple packets. */
+        /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        fragment_option = (NX_IPV6_HEADER_FRAGMENT_OPTION *)first_fragment -> nx_packet_last -> nx_packet_append_ptr;
+        first_fragment -> nx_packet_append_ptr += sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION);
+        first_fragment -> nx_packet_length += (ULONG)sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION);
+
+        fragment_option -> nx_ipv6_header_fragment_option_reserved = 0;
+        fragment_option -> nx_ipv6_header_fragment_option_next_header = next_header;
+
+        if (!last_fragment)
+        {
+            fragment_option -> nx_ipv6_header_fragment_option_offset_flag = (USHORT)(fragment_offset + 1);
+        }
+        else
+        {
+            fragment_option -> nx_ipv6_header_fragment_option_offset_flag = (USHORT)fragment_offset;
+        }
+
+        /* Convert to network byte order. */
+        NX_CHANGE_USHORT_ENDIAN(fragment_option -> nx_ipv6_header_fragment_option_offset_flag);
+
+        fragment_option -> nx_ipv6_header_fragment_option_packet_id = packet_id;
+
+        /* Restore the nx_packet_last and the prepend pointer within the last packet. */
+        source_packet -> nx_packet_last = previous_packet;
+        source_packet -> nx_packet_last -> nx_packet_prepend_ptr = fragmentable_ptr;
+
+        /* Copy the rest of the frame. */
+        if (_nx_ipv6_packet_copy(source_packet, first_fragment, fragment_size))
+        {
+            break;
+        }
+
+        /*
+           Set up the IP frame length.  first_fragment -> nx_packet_prepend_ptr points to the
+           beginning of the IPv6 header.
+         */
+        /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        ipv6_header = (NX_IPV6_HEADER *)first_fragment -> nx_packet_prepend_ptr;
+
+        /* Pick up the 2nd word in the IP header. */
+        val = ipv6_header -> nx_ip_header_word_1;
+
+        /* Convert to host byte order. */
+        NX_CHANGE_ULONG_ENDIAN(val);
+
+        val = val & 0x0000FFFF;
+
+        word_1 = (ULONG)(((fragment_size + unfragmentable_size - sizeof(NX_IPV6_HEADER)) + sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION)) << 16);
+        word_1 = val | word_1;
+
+        /* Convert to network byte order. */
+        NX_CHANGE_ULONG_ENDIAN(word_1);
+
+        ipv6_header -> nx_ip_header_word_1 = word_1;
+
+        fragmentable_ptr = source_packet -> nx_packet_last -> nx_packet_prepend_ptr;
+
+        fragment_offset += fragment_size;
+
+        /* This fragment is ready to be transmitted. */
+        /* Send the packet to the associated driver for output.  */
+        first_fragment -> nx_packet_length = unfragmentable_size + fragment_size;
+        first_fragment -> nx_packet_length += (ULONG)sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION);
+        driver_request.nx_ip_driver_packet =   first_fragment;
+
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Increment the IP fragments sent count.  */
+        ip_ptr -> nx_ip_total_fragments_sent++;
+
+        /* Increment the IP packet sent count.  */
+        ip_ptr -> nx_ip_total_packets_sent++;
+
+        /* Increment the IP bytes sent count.  */
+        ip_ptr -> nx_ip_total_bytes_sent += first_fragment -> nx_packet_length - (ULONG)sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION);
+#endif /* !NX_DISABLE_IP_INFO */
+
+        /* Add debug information. */
+        NX_PACKET_DEBUG(__FILE__, __LINE__, source_packet);
+
+        (source_packet -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached -> nx_interface_link_driver_entry)(&driver_request);
+
+        first_fragment = NX_NULL;
+    }
+
+    /* Release the original packet. */
+    _nx_packet_transmit_release(source_packet);
+
+    /* In case the fragmentation process fails above, frist_fragment
+       still contains partial data. Free these fragments before
+       exiting this function. */
+    if (first_fragment)
+    {
+        _nx_packet_release(first_fragment);
+    }
+
+    return;
+}
+
+#endif /* FEATURE_NX_IPV6 && NX_DISABLE_FRAGMENTATION*/
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_header_add.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_header_add.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_header_add.c	(revision 69)
@@ -0,0 +1,341 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_ipv6.h"
+#include "nx_packet.h"
+#include "nx_icmpv6.h"
+
+#ifdef NX_IPSEC_ENABLE
+#include "nx_ipsec.h"
+#endif /* NX_IPSEC_ENABLE */
+
+#ifdef FEATURE_NX_IPV6
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_header_add                                 PORTABLE C      */
+/*                                                           6.1.8        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function prepends an IPv6 header.                              */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_pptr                           Pointer to packet to send     */
+/*    protocol                              Protocol being encapsulated   */
+/*    payload_size                          Size of the payload           */
+/*    hop_limit                             Hop limit value to set in IP  */
+/*                                             header.                    */
+/*    src_address                           Source address                */
+/*    dest_address                          Destination address           */
+/*    fragment                              Fragmentable or not           */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_packet_transmit_release           Release transmit packet       */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ipv6_packet_send                  IPv6 packet transmit process  */
+/*    _nx_icmpv6_send_ns                    Send NS packet                */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  08-02-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            supported TCP/IP offload,   */
+/*                                            resulting in version 6.1.8  */
+/*                                                                        */
+/**************************************************************************/
+UINT _nx_ipv6_header_add(NX_IP *ip_ptr, NX_PACKET **packet_pptr,
+                         ULONG protocol, ULONG payload_size, ULONG hop_limit,
+                         ULONG *src_address, ULONG *dest_address, ULONG *fragment)
+{
+
+NX_IPV6_HEADER            *ip_header_ptr;
+NX_PACKET                 *packet_ptr = *packet_pptr;
+#ifdef NX_IPSEC_ENABLE
+UINT                       status = NX_SUCCESS;
+UCHAR                      is_hw_processed = NX_FALSE;
+USHORT                     short_val;
+#endif /* NX_IPSEC_ENABLE */
+
+#if defined(NX_DISABLE_IP_INFO) && !defined(NX_IPSEC_ENABLE) && !defined(NX_ENABLE_IP_PACKET_FILTER)
+    NX_PARAMETER_NOT_USED(ip_ptr);
+#endif
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+    if (fragment)
+    {
+#ifndef NX_DISABLE_FRAGMENTATION
+        /* By default, it is fragmentable. */
+        *fragment = NX_TRUE;
+#else
+        /* By default, it is not fragmentable. */
+        *fragment = NX_FALSE;
+#endif /* NX_DISABLE_FRAGMENTATION */
+    }
+
+#ifndef NX_DISABLE_IP_INFO
+
+    /* Increment the total send requests counter.  */
+    ip_ptr -> nx_ip_total_packet_send_requests++;
+#endif
+
+    /* Initialize the IP header incase this function returns fail. */
+    packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr;
+
+#ifdef NX_IPSEC_ENABLE
+    /* Check if this packet is continued after HW crypto engine. */
+    if (packet_ptr -> nx_packet_ipsec_sa_ptr &&
+        ((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_sa_mode == NX_IPSEC_TRANSPORT_MODE &&
+        (packet_ptr -> nx_packet_ipsec_state == NX_IPSEC_AH_PACKET ||
+         packet_ptr -> nx_packet_ipsec_state == NX_IPSEC_ESP_PACKET))
+    {
+        is_hw_processed = NX_TRUE;
+    }
+
+    /* IPsec transport mode enabled? */
+    if (packet_ptr -> nx_packet_ipsec_sa_ptr &&
+        packet_ptr -> nx_packet_ipsec_state != NX_IPSEC_ESP_PACKET &&
+        packet_ptr -> nx_packet_ipsec_state != NX_IPSEC_AH_PACKET &&
+        ((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_sa_mode == NX_IPSEC_TRANSPORT_MODE)
+    {
+
+        /* Yes, process the packet */
+        status = _nx_ipsec_ip_output_packet_process(ip_ptr, &packet_ptr, protocol, payload_size, (&payload_size));
+
+        /* Check for errors. */
+        if ((status != NX_SUCCESS) &&
+            (status != NX_IPSEC_HW_PENDING))
+        {
+
+            /* IPsec output packet process failed. */
+
+            /* Release the packet.  */
+            _nx_packet_transmit_release(packet_ptr);
+
+            return(status);
+        }
+
+        /* Update the packet pointer. */
+        *packet_pptr = packet_ptr;
+
+        /* Change protocol to ESP or AH. */
+        protocol = (((NX_IPSEC_SA *)packet_ptr -> nx_packet_ipsec_sa_ptr) -> nx_ipsec_sa_protocol);
+
+#ifndef NX_DISABLE_FRAGMENTATION
+        /* Set the fragment flag to false. Transport mode SAs have been defined to not carry fragments (IPv4 or IPv6), RFC 4301 page 66 and page 88.*/
+        if (fragment)
+        {
+            *fragment = NX_FALSE;
+        }
+#endif /* NX_DISABLE_FRAGMENTATION */
+    }
+#endif /* NX_IPSEC_ENABLE  */
+
+#ifdef NX_IPSEC_ENABLE
+    if (!is_hw_processed)
+    {
+#endif /* NX_IPSEC_ENABLE  */
+        /* Prepend the IP header to the packet.  First, make room for the IP header.  */
+        packet_ptr -> nx_packet_prepend_ptr =  packet_ptr -> nx_packet_prepend_ptr - sizeof(NX_IPV6_HEADER);
+
+        /* Increase the packet length.  */
+        packet_ptr -> nx_packet_length =  packet_ptr -> nx_packet_length + (ULONG)sizeof(NX_IPV6_HEADER);
+
+        /* Increase header length. */
+        packet_ptr -> nx_packet_ip_header_length = (UCHAR)(packet_ptr -> nx_packet_ip_header_length +
+                                                           sizeof(NX_IPV6_HEADER));
+
+
+        /* If the interface IP address is not valid (in DAD state), only ICMP is allowed */
+        if (packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_VALID)
+        {
+
+#ifndef NX_DISABLE_IPV6_DAD
+        NX_ICMPV6_HEADER *icmpv6_header = (NX_ICMPV6_HEADER *)(packet_ptr -> nx_packet_prepend_ptr +
+                                                               packet_ptr -> nx_packet_ip_header_length);
+
+            /* Interface IP address is invalid.  Before dropping the outgoing packet,
+               check whether the interface address is in tentative state and the protocol
+               is ICMPv6-DAD. */
+
+            /* This check is needed only if DAD is not disabled.
+               If DAD is disabled, we drop the packet. */
+            if (!((protocol == NX_PROTOCOL_ICMPV6) &&
+                  (packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_state == NX_IPV6_ADDR_STATE_TENTATIVE) &&
+                  (icmpv6_header -> nx_icmpv6_header_type == NX_ICMPV6_NEIGHBOR_SOLICITATION_TYPE)))
+#endif /* NX_DISABLE_IPV6_DAD */
+            {
+#ifndef NX_DISABLE_IP_INFO
+
+                /* Increment the IP invalid packet error.  */
+                ip_ptr -> nx_ip_invalid_transmit_packets++;
+#endif
+
+                /* Release the packet.  */
+                _nx_packet_transmit_release(packet_ptr);
+
+                /* Return... nothing more can be done!  */
+                return(NX_NO_INTERFACE_ADDRESS);
+            }
+        }
+
+        /* If the IP header won't fit, return an error.  */
+        /*lint -e{946} suppress pointer subtraction, since it is necessary. */
+        NX_ASSERT(packet_ptr -> nx_packet_prepend_ptr >= packet_ptr -> nx_packet_data_start);
+
+        /* Build the IP header.  */
+        /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
+        packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr;
+
+        /* bits 31-28: IP version.  Bits 27-20: Traffic Class.  Bits 19-00: Flow Lable */
+        ip_header_ptr -> nx_ip_header_word_0 = (ULONG)(6 << 28);
+        NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_0);
+
+        /* bits 31-16: payload size.  Bits 15-8: Next Header.   Bits 7-0 Hop limit */
+        /* ip_header_ptr -> nx_ip_header_word_1 = (payload_size << 16) | (protocol << 8) | (ip_ptr -> nx_ipv6_hop_limit);*/
+        ip_header_ptr -> nx_ip_header_word_1 = (payload_size << 16) | (protocol << 8) | (hop_limit);
+        NX_CHANGE_ULONG_ENDIAN(ip_header_ptr -> nx_ip_header_word_1);
+
+
+        /* Fill in local IPv6 address as sender's address*/
+        COPY_IPV6_ADDRESS(src_address, ip_header_ptr -> nx_ip_header_source_ip);
+
+        COPY_IPV6_ADDRESS(dest_address, ip_header_ptr -> nx_ip_header_destination_ip);
+
+        /* Fix endianness */
+        NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header_ptr -> nx_ip_header_destination_ip);
+        NX_IPV6_ADDRESS_CHANGE_ENDIAN(ip_header_ptr -> nx_ip_header_source_ip);
+
+#ifdef NX_IPSEC_ENABLE
+    }
+    else
+    {
+
+        /* Fix payload size.  */
+        /* Build the IP header.  */
+        ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_prepend_ptr;
+
+        payload_size -= sizeof(NX_IPV6_HEADER);
+        short_val = (USHORT)payload_size;
+        NX_CHANGE_USHORT_ENDIAN(short_val);
+        payload_size = short_val;
+
+        /* First clear payload_size field.  */
+        ip_header_ptr -> nx_ip_header_word_1 &= 0xFFFF0000;
+
+        /* Fill payload_size field.  */
+        ip_header_ptr -> nx_ip_header_word_1 |= short_val;
+    }
+
+    /* IPsec tunnel mode. */
+    if (packet_ptr -> nx_packet_ipsec_sa_ptr &&
+        packet_ptr -> nx_packet_ipsec_state != NX_IPSEC_ESP_PACKET &&
+        packet_ptr -> nx_packet_ipsec_state != NX_IPSEC_AH_PACKET &&
+        ((NX_IPSEC_SA *)(packet_ptr -> nx_packet_ipsec_sa_ptr)) -> nx_ipsec_sa_mode == NX_IPSEC_TUNNEL_MODE)
+    {
+        status = _nx_ipsec_ip_output_packet_process(ip_ptr, &packet_ptr, NX_PROTOCOL_IPV6, (ULONG)payload_size, (ULONG *)(&payload_size));
+
+        if ((status != NX_SUCCESS) &&
+            (status != NX_IPSEC_HW_PENDING))
+        {
+            /* IPsec output packet process failed. */
+
+            /* Release the packet.  */
+            _nx_packet_transmit_release(packet_ptr);
+
+            return(status);
+        }
+
+        /* Update the packet pointer. */
+        *packet_pptr = packet_ptr;
+
+        /* Tunnel consume the packet. */
+        return(NX_IPSEC_PKT_CONT);
+    }
+
+    /* ICV calculation before the packet sent over the wire if packet went through AH processing. */
+    if (packet_ptr -> nx_packet_ipsec_sa_ptr &&
+        packet_ptr -> nx_packet_ipsec_state == NX_IPSEC_AH_PACKET)
+    {
+        status = ip_ptr -> nx_ip_ipsec_authentication_header_transmit(ip_ptr, &packet_ptr, protocol, 1);
+
+        if ((status != NX_SUCCESS) &&
+            (status != NX_IPSEC_HW_PENDING))
+        {
+            /* Release the packet.  */
+            _nx_packet_transmit_release(packet_ptr);
+
+            return(status);
+        }
+
+        /* Update the packet pointer. */
+        *packet_pptr = packet_ptr;
+    }
+
+    /* HW crypto driver is processing packet. */
+    if (status == NX_IPSEC_HW_PENDING)
+    {
+
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Decrement the total send requests counter.  */
+        ip_ptr -> nx_ip_total_packet_send_requests--;
+#endif
+        return(status);
+    }
+
+#endif /* NX_IPSEC_ENABLE */
+
+    return(NX_SUCCESS);
+}
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_multicast_join.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_multicast_join.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_multicast_join.c	(revision 69)
@@ -0,0 +1,105 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#ifdef FEATURE_NX_IPV6
+#include "nx_ip.h"
+#include "nx_ipv6.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_multicast_join                             PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    Joins IPv6 multicast group. This is an internal function.  The      */
+/*    caller must hold the IP protection (mutex).                         */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                IP instance pointer           */
+/*    multicast_address                     IPv6 multicast address        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Completion status             */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    tx_mutex_get                          Obtain protection mutex       */
+/*    tx_mutex_put                          Release protection mutex      */
+/*    (ip_link_driver)                      Device driver entry point     */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    nx_icmpv6_process_ra                                                */
+/*    nxd_ipv6_enable                                                     */
+/*    nxd_ipv6_address_set                                                */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT _nx_ipv6_multicast_join(NX_IP *ip_ptr, ULONG *multicast_addr, NX_INTERFACE *nx_interface)
+{
+
+NX_IP_DRIVER driver_request;
+
+
+    /* Construct a driver command. */
+    driver_request.nx_ip_driver_ptr = ip_ptr;
+    driver_request.nx_ip_driver_command = NX_LINK_MULTICAST_JOIN;
+    driver_request.nx_ip_driver_physical_address_msw = 0x00003333;
+    driver_request.nx_ip_driver_physical_address_lsw = multicast_addr[3];
+    driver_request.nx_ip_driver_interface = nx_interface;
+
+    /* Obtain the IP mutex so we can search the multicast join list.  */
+    tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
+
+    /* Call the device driver with the driver request. */
+    (nx_interface -> nx_interface_link_driver_entry)(&driver_request);
+
+    /* Release the protection over the IP instance.  */
+    tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+
+    /*lint -e{644} suppress variable might not be initialized, since "nx_ip_driver_status" was initialized in nx_interface_link_driver_entry. */
+    return(driver_request.nx_ip_driver_status);
+}
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_multicast_leave.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_multicast_leave.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_multicast_leave.c	(revision 69)
@@ -0,0 +1,104 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#ifdef FEATURE_NX_IPV6
+#include "nx_ip.h"
+#include "nx_ipv6.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_multicast_leave                            PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    Leave IPv6 multicast group. This is an internal function.  The      */
+/*    caller must hold the IP protection (mutex).                         */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                IP instance pointer           */
+/*    multicast_address                     IPv6 multicast address        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Completion status             */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    tx_mutex_get                          Obtain protection mutex       */
+/*    tx_mutex_put                          Release protection mutex      */
+/*    (ip_link_driver)                      Device driver entry point     */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nxd_ipv6_address_delete                                            */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT _nx_ipv6_multicast_leave(NX_IP *ip_ptr, ULONG *multicast_addr, NX_INTERFACE *nx_interface)
+{
+
+NX_IP_DRIVER driver_request;
+
+
+    /* Construct a driver command. */
+    driver_request.nx_ip_driver_ptr = ip_ptr;
+    driver_request.nx_ip_driver_command = NX_LINK_MULTICAST_LEAVE;
+    driver_request.nx_ip_driver_physical_address_msw = 0x00003333;
+    driver_request.nx_ip_driver_physical_address_lsw = multicast_addr[3];
+    driver_request.nx_ip_driver_interface = nx_interface;
+
+    /* Obtain the IP mutex so we can search the multicast join list.  */
+    tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
+
+
+    /* Call the device driver with the driver request. */
+    (nx_interface -> nx_interface_link_driver_entry)(&driver_request);
+
+    /* Release the protection over the IP instance.  */
+    tx_mutex_put(&(ip_ptr -> nx_ip_protection));
+
+    /*lint -e{644} suppress variable might not be initialized, since "nx_ip_driver_status" was initialized in nx_interface_link_driver_entry. */
+    return(driver_request.nx_ip_driver_status);
+}
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_option_error.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_option_error.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_option_error.c	(revision 69)
@@ -0,0 +1,139 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_icmpv6.h"
+
+#ifdef FEATURE_NX_IPV6
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_option_error                               PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function handles an invalid Options header packet by examining */
+/*    the option header option type's most significant bits and           */
+/*    determining if an error message is sent and if the rest of the      */
+/*    packet should be processed or discarded.                            */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to packet to send     */
+/*    option_type                           The type of option            */
+/*    offset                                Where the error occurs        */
+/*                                                                        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS                             Skip this option; no errors  */
+/*    NX_OPTION_HEADER_ERROR                 Error; Drop the entire packet*/
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ipv6_process_hop_by_hop_option                                  */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT _nx_ipv6_option_error(NX_IP *ip_ptr, NX_PACKET *packet_ptr, UCHAR option_type, UINT offset)
+{
+
+UINT rv = NX_SUCCESS;
+
+/*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+NX_IPV6_HEADER *ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_ip_header;
+
+    /* Top 2 bits of the option type indicate how we shall process this option
+       in case of an error. */
+    switch (option_type >> 6)
+    {
+
+    case 3: /* Discard the packet and send ICMP Parameter Problem to unicast address */
+        if ((ip_header_ptr -> nx_ip_header_destination_ip[0] & (ULONG)0xFF000000) == (ULONG)0xFF000000)
+        {
+
+            /* If the destination address is a multicast address, we discard the packet. */
+            rv = NX_OPTION_HEADER_ERROR;
+            break;
+        }
+    /*
+       No need to break here:  execute the next two cases:
+       (1) transmit ICMP error message
+       (2) release the packet.
+     */
+
+    /*lint -e{825} suppress fallthrough, since it is necessary.  */ /* fallthrough */
+    case 2: /* Discard the packet and send ICMP Parameter Problem */
+
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+
+        NX_ICMPV6_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, 2, (ULONG)(offset + sizeof(NX_IPV6_HEADER)));
+#else
+        NX_PARAMETER_NOT_USED(ip_ptr);
+        NX_PARAMETER_NOT_USED(offset);
+#endif
+
+    /* No break here.  Execute the next statement to release the packet. */
+
+    /*lint -e{825} suppress fallthrough, since it is necessary.  */ /* fallthrough */
+    case 1: /* Discard the packet */
+
+        /* Error status - Drop the packet */
+        rv = NX_OPTION_HEADER_ERROR;
+        break;
+
+    case 0: /* Skip over this option and continue processing the rest of the packet. */
+    default:
+        break;
+    }
+
+    return(rv);
+}
+
+
+#endif /*  FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_packet_copy.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_packet_copy.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_packet_copy.c	(revision 69)
@@ -0,0 +1,243 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol version 6 (IPv6)                                  */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "tx_api.h"
+#include "nx_api.h"
+#include "nx_ipv6.h"
+
+
+#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_FRAGMENTATION)
+
+/* Define the status 'bits' of the copy flag field. */
+#define PACKET_MORE_TO_COPY 1
+#define PACKET_ADD_BUFFER   2
+#define PACKET_COPY_DONE    4
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_packet_copy                                PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This internal function copies packet data between packets.          */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    source_pkt_head             Pointer to source packet chain.         */
+/*    dest_pkt_head               Pointer to destination packet chain.    */
+/*    size                        Number of bytes to copy.                */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS                   Successful completion                  */
+/*    NX_NOT_SUCCESSFUL            Error with packet copy                 */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ipv6_fragment_process                                           */
+/*                                                                        */
+/*                                                                        */
+/*  NOTE                                                                  */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT _nx_ipv6_packet_copy(NX_PACKET *source_pkt_head, NX_PACKET *dest_pkt_head, UINT size)
+{
+
+UINT       bytes_remaining;
+NX_PACKET *source_pkt, *dest_pkt;
+UINT       bytes_to_copy;
+ULONG     *source_ptr, *dest_ptr;
+UCHAR     *source_byte, *dest_byte;
+UINT       flag;
+
+
+    /* Number of bytes to be copied. */
+    bytes_remaining = size;
+
+    /* Obtain points to the source and destination packets. */
+    source_pkt = source_pkt_head -> nx_packet_last;
+    dest_pkt = dest_pkt_head -> nx_packet_last;
+
+    while (bytes_remaining > 0)
+    {
+
+        /* Make sure source or destination packets are valid. */
+        if ((source_pkt == NX_NULL) || (dest_pkt == NX_NULL))
+        {
+            return(NX_NOT_SUCCESSFUL);
+        }
+
+        /*
+           figure out the amount of bytes we can copy in this iteration.
+           At the end of the interation, we shall be able to "close" either the
+           source packet or the destination packet.
+         */
+
+        bytes_to_copy = bytes_remaining;
+
+        flag = PACKET_COPY_DONE;
+
+        /* Check if the source packet is running out of data. */
+        /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+        if (bytes_to_copy > (UINT)(source_pkt -> nx_packet_append_ptr - source_pkt -> nx_packet_prepend_ptr))
+        {
+
+            /* It is. Set flag to PACKET_MORE_TO_COPY, indicating that there is more to be copied
+               from the following buffer.  */
+            /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+            bytes_to_copy = (UINT)(source_pkt -> nx_packet_append_ptr - source_pkt -> nx_packet_prepend_ptr);
+            flag = PACKET_MORE_TO_COPY;
+        }
+
+        /* Check if the destination packet is running ouf of space.  */
+        /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+        if (bytes_to_copy > (UINT)(dest_pkt -> nx_packet_data_end - dest_pkt -> nx_packet_append_ptr))
+        {
+
+            /* It is. Set the 2nd bit in the flag to indicate that at the the end of the
+               iteration we will need to chain another buffer on the destination packet.*/
+            /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+            bytes_to_copy = (UINT)(dest_pkt -> nx_packet_data_end - dest_pkt -> nx_packet_append_ptr);
+            flag = PACKET_ADD_BUFFER;
+        }
+
+        /* Adjust packet pointers. */
+        /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        dest_ptr = (ULONG *)dest_pkt -> nx_packet_append_ptr;
+        dest_pkt -> nx_packet_append_ptr += bytes_to_copy;
+        dest_pkt -> nx_packet_length -= bytes_to_copy;
+
+        /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        source_ptr = (ULONG *)source_pkt -> nx_packet_prepend_ptr;
+        source_pkt -> nx_packet_prepend_ptr += bytes_to_copy;
+
+        while (bytes_to_copy)
+        {
+            /* Loop unrolling: copy 32 bytes in one iteration. */
+            switch (bytes_to_copy >> 2)
+            {
+            default:
+                *dest_ptr++ = *source_ptr++;
+            /*lint -e{825} suppress fallthrough, since it is necessary.  */ /* fallthrough */
+            case 7:
+                *dest_ptr++ = *source_ptr++;
+            /*lint -e{825} suppress fallthrough, since it is necessary.  */ /* fallthrough */
+            case 6:
+                *dest_ptr++ = *source_ptr++;
+            /*lint -e{825} suppress fallthrough, since it is necessary.  */ /* fallthrough */
+            case 5:
+                *dest_ptr++ = *source_ptr++;
+            /*lint -e{825} suppress fallthrough, since it is necessary.  */ /* fallthrough */
+            case 4:
+                *dest_ptr++ = *source_ptr++;
+            /*lint -e{825} suppress fallthrough, since it is necessary.  */ /* fallthrough */
+            case 3:
+                *dest_ptr++ = *source_ptr++;
+            /*lint -e{825} suppress fallthrough, since it is necessary.  */ /* fallthrough */
+            case 2:
+                *dest_ptr++ = *source_ptr++;
+            /*lint -e{825} suppress fallthrough, since it is necessary.  */ /* fallthrough */
+            case 1:
+                *dest_ptr++ = *source_ptr++;
+            }
+            if (bytes_to_copy >= 32)
+            {
+                bytes_to_copy -= 32;
+                bytes_remaining -= 32;
+            }
+            else
+            {
+
+                /* Copy bytes less than 4. */
+                /*lint --e{928} suppress cast from pointer to pointer, since it is necessary  */
+                source_byte = (UCHAR *)source_ptr;
+                dest_byte = (UCHAR *)dest_ptr;
+                switch (bytes_to_copy & 3)
+                {
+                case 3:
+                    *dest_byte++ = *source_byte++;
+                /*lint -e{825} suppress fallthrough, since it is necessary.  */ /* fallthrough */
+                case 2:
+                    *dest_byte++ = *source_byte++;
+                /*lint -e{825} suppress fallthrough, since it is necessary.  */ /* fallthrough */
+                case 1:
+                    *dest_byte++ = *source_byte++;
+                    break;
+                default:
+                    break;
+                }
+
+                bytes_remaining -= bytes_to_copy;
+                bytes_to_copy = 0;
+            }
+        }
+
+        /* Check if the flag has been set to more data to copy. */
+        if (flag & PACKET_MORE_TO_COPY)
+        {
+            source_pkt_head -> nx_packet_last = source_pkt -> nx_packet_next;
+            source_pkt = source_pkt_head -> nx_packet_last;
+        }
+
+        /* Check if we need to chain another buffer to the packet chain for more data copy. */
+        if (flag & PACKET_ADD_BUFFER)
+        {
+            dest_pkt_head -> nx_packet_last = dest_pkt -> nx_packet_next;
+            dest_pkt = dest_pkt -> nx_packet_next;
+        }
+
+        /* Check if we are done. */
+        if (flag & PACKET_COPY_DONE)
+        {
+
+            /* We are. */
+            break;
+        }
+    }
+
+    return(NX_SUCCESS);
+}
+
+
+#endif /* FEATURE_NX_IPV6 && NX_DISABLE_FRAGMENTATION*/
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_packet_send.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_packet_send.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_packet_send.c	(revision 69)
@@ -0,0 +1,586 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_ipv6.h"
+#include "nx_packet.h"
+#include "nx_icmpv6.h"
+
+#ifdef FEATURE_NX_IPV6
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_packet_send                                PORTABLE C      */
+/*                                                           6.1.8        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function prepends an IP header and sends an IP packet to the   */
+/*    appropriate link driver.  Caller needs to fill in the correct       */
+/*    source and destination addresses into the packet source and         */
+/*    destination address.  Caller also makes sure that the packet        */
+/*    interface address is valid (not in tentative state), and source     */
+/*    address is not unspecified e.g. NULL.                               */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to packet to send     */
+/*    protocol                              Protocol being encapsulated   */
+/*    payload_size                          Size of the payload           */
+/*    hop_limit                             Hop limit value to set in IP  */
+/*                                             header.                    */
+/*    src_address                           Source address                */
+/*    dest_address                          Destination address           */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ipv6_header_add                   Add IPv6 header               */
+/*    _nx_packet_transmit_release           Release transmit packet       */
+/*    _nx_nd_cache_add_entry                Add new entry to ND Cache     */
+/*    IPv6_Address_Type                     Find IPv6 address type        */
+/*    _nx_packet_copy                       Packet copy                   */
+/*    _nx_ip_packet_deferred_receive        Places received packets in    */
+/*                                            deferred packet queue       */
+/*    _nx_icmpv6_send_ns                    Send neighbor solicitation    */
+/*    _nxd_ipv6_search_onlink               Find onlink match             */
+/*    _nx_ipv6_fragment_processing          Fragment processing           */
+/*    (ip_link_driver)                      User supplied link driver     */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  08-02-2021     Yuxin Zhou               Modified comment(s), and      */
+/*                                            supported TCP/IP offload,   */
+/*                                            resulting in version 6.1.8  */
+/*                                                                        */
+/**************************************************************************/
+VOID _nx_ipv6_packet_send(NX_IP *ip_ptr, NX_PACKET *packet_ptr,
+                          ULONG protocol, ULONG payload_size, ULONG hop_limit,
+                          ULONG *src_address, ULONG *dest_address)
+{
+
+UINT                       status = NX_SUCCESS;
+ULONG                      address_type;
+UINT                       next_hop_mtu;
+ULONG                      fragment = NX_TRUE;
+#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
+NX_IPV6_DESTINATION_ENTRY *next_hop_dest_entry_ptr;
+#endif /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
+NX_IP_DRIVER               driver_request;
+NX_PACKET                 *remove_packet;
+NX_PACKET                 *packet_copy;
+UINT                       same_address;
+NX_INTERFACE              *if_ptr;
+NX_IPV6_DESTINATION_ENTRY *dest_entry_ptr;
+
+    /*lint -e{644} suppress variable might not be initialized, since "packet_ptr" was initialized. */
+    if_ptr = packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached;
+
+    /* Interface can not be NULL. */
+    NX_ASSERT(if_ptr != NX_NULL);
+
+#ifdef NX_ENABLE_TCPIP_OFFLOAD
+    if (if_ptr -> nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD)
+    {
+#ifndef NX_DISABLE_IP_INFO
+
+        /* Increment the IP invalid packet error.  */
+        ip_ptr -> nx_ip_invalid_transmit_packets++;
+#endif
+
+        /* Ignore sending all packets for TCP/IP offload. Release the packet.  */
+        _nx_packet_transmit_release(packet_ptr);
+
+        /* Return... nothing more can be done!  */
+        return;
+    }
+#endif /* NX_ENABLE_TCPIP_OFFLOAD */
+
+    /* Add IPv6 header. */
+    if (_nx_ipv6_header_add(ip_ptr, &packet_ptr, protocol, payload_size,
+                            hop_limit, src_address, dest_address, &fragment) != NX_SUCCESS)
+    {
+
+        /* Failed to add header. */
+        return;
+    }
+
+#ifdef NX_ENABLE_IP_PACKET_FILTER
+    /* Check if the IP packet filter is set. */
+    if (ip_ptr -> nx_ip_packet_filter)
+    {
+
+        /* Yes, call the IP packet filter routine. */
+        if (ip_ptr -> nx_ip_packet_filter((VOID *)(packet_ptr -> nx_packet_prepend_ptr),
+                                          NX_IP_PACKET_OUT) != NX_SUCCESS)
+        {
+
+            /* Drop the packet. */
+            _nx_packet_transmit_release(packet_ptr);
+            return;
+        }
+    }
+
+    /* Check if the IP packet filter extended is set. */
+    if (ip_ptr -> nx_ip_packet_filter_extended)
+    {
+
+        /* Yes, call the IP packet filter extended routine. */
+        if (ip_ptr -> nx_ip_packet_filter_extended(ip_ptr, packet_ptr, NX_IP_PACKET_OUT) != NX_SUCCESS)
+        {
+
+            /* Drop the packet. */
+            _nx_packet_transmit_release(packet_ptr);
+            return;
+        }
+    }
+#endif /* NX_ENABLE_IP_PACKET_FILTER */
+
+    next_hop_mtu = if_ptr -> nx_interface_ip_mtu_size;
+    packet_ptr -> nx_packet_ip_header = packet_ptr -> nx_packet_prepend_ptr;
+
+    /* Check if the host is sending itself a packet. */
+    same_address = (UINT)CHECK_IPV6_ADDRESSES_SAME(dest_address, src_address);
+
+    /* If it is, consider this a loopback address. */
+    if (same_address == 1)
+    {
+
+        address_type = IPV6_ADDRESS_LOOPBACK;
+    }
+    else
+    {
+
+        /* Otherwise check if this packet sending to a known loopback address. */
+        address_type = IPv6_Address_Type(dest_address);
+    }
+
+    /* Handle the internal loopback case. */
+    if (address_type == IPV6_ADDRESS_LOOPBACK)
+    {
+
+        if (_nx_packet_copy(packet_ptr, &packet_copy, ip_ptr -> nx_ip_default_packet_pool, NX_NO_WAIT) == NX_SUCCESS)
+        {
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+
+            /* Compute checksum for upper layer protocol. */
+            /*lint -e{644} suppress variable might not be initialized, since "packet_copy" was initialized as long as return value is NX_SUCCESS. */
+            if (packet_copy -> nx_packet_interface_capability_flag)
+            {
+                _nx_ip_packet_checksum_compute(packet_copy);
+            }
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+            /* Get the interface of copied packet. */
+            /*lint --e{644} suppress variable might not be initialized, since "packet_copy" was initialized as long as return value is NX_SUCCESS. */
+            packet_copy -> nx_packet_address.nx_packet_interface_ptr = packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached;
+
+#ifndef NX_DISABLE_IP_INFO
+
+            /* Increment the IP packet sent count. */
+            ip_ptr -> nx_ip_total_packets_sent++;
+
+            /* Increment the IP bytes sent count. */
+            ip_ptr -> nx_ip_total_bytes_sent += packet_ptr -> nx_packet_length - (ULONG)sizeof(NX_IPV6_HEADER);
+#endif
+
+            /* Send the packet to this IP's receive processing like it came in from the driver. */
+            _nx_ip_packet_deferred_receive(ip_ptr, packet_copy);
+        }
+#ifndef NX_DISABLE_IP_INFO
+        else
+        {
+            /* Increment the IP send packets dropped count. */
+            ip_ptr -> nx_ip_send_packets_dropped++;
+
+            /* Increment the IP transmit resource error count. */
+            ip_ptr -> nx_ip_transmit_resource_errors++;
+        }
+#endif
+        /* Release the transmit packet. */
+        _nx_packet_transmit_release(packet_ptr);
+        return;
+    }
+
+    /* Initial the driver request. */
+    driver_request.nx_ip_driver_ptr                  = ip_ptr;
+    driver_request.nx_ip_driver_command              = NX_LINK_PACKET_SEND;
+    driver_request.nx_ip_driver_packet               = packet_ptr;
+    driver_request.nx_ip_driver_interface            = NX_NULL;
+
+    /* Determine if physical mapping is needed by this link driver. */
+    if (if_ptr -> nx_interface_address_mapping_needed)
+    {
+
+        /* Is this packet a multicast ? */
+        if ((dest_address[0] & (ULONG)0xFF000000) == (ULONG)0xFF000000)
+        {
+
+
+            /* Set up the driver request. */
+            driver_request.nx_ip_driver_physical_address_msw = 0x00003333;
+            driver_request.nx_ip_driver_physical_address_lsw = dest_address[3];
+            driver_request.nx_ip_driver_interface            = if_ptr;
+
+            /* It is; is path MTU enabled? */
+#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
+
+            /* It is. We will check the path MTU for the packet destination to
+               determine if we need to fragment the packet. */
+
+            /* Lookup the multicast destination in the destination table.  */
+            status = _nx_icmpv6_dest_table_find(ip_ptr, dest_address, &dest_entry_ptr, 0, 0);
+
+            /* Did we find it in the table? */
+            /*lint -e{644} suppress variable might not be initialized, since "dest_entry_ptr" was initialized as long as status is NX_SUCCESS. */
+            if (status == NX_SUCCESS)
+            {
+                next_hop_mtu = dest_entry_ptr -> nx_ipv6_destination_entry_path_mtu;
+            }
+
+#endif  /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
+        }
+        else
+        {
+
+        /* Obtain MAC address */
+        ND_CACHE_ENTRY *NDCacheEntry = NX_NULL;
+        ULONG           next_hop_address[4];
+
+            SET_UNSPECIFIED_ADDRESS(next_hop_address);
+
+            /* Lookup the packet destination in the destination table. */
+            status = _nx_icmpv6_dest_table_find(ip_ptr, dest_address, &dest_entry_ptr, 0, 0);
+
+            /* Was a matching entry found? */
+            if (status != NX_SUCCESS)
+            {
+
+                /* No; If the packet is either onlink or there is no default router,
+                   just copy the packet destination address to the 'next hop' address.  */
+
+                if (_nxd_ipv6_search_onlink(ip_ptr, dest_address))
+                {
+                    COPY_IPV6_ADDRESS(dest_address, next_hop_address);
+
+                    /* Add the next_hop in destination table. */
+                    status = _nx_icmpv6_dest_table_add(ip_ptr, dest_address, &dest_entry_ptr,
+                                                       next_hop_address, if_ptr -> nx_interface_ip_mtu_size,
+                                                       NX_WAIT_FOREVER, packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr);
+
+                    /* Get the NDCacheEntry. */
+                    if (status == NX_SUCCESS)
+                    {
+                        NDCacheEntry = dest_entry_ptr -> nx_ipv6_destination_entry_nd_entry;
+                    }
+                }
+                /* Check whether or not we have a default router. */
+                /* Suppress cast of pointer to pointer, since it is necessary  */
+                else if (_nxd_ipv6_router_lookup(ip_ptr, if_ptr, next_hop_address, /*lint -e{929}*/ (void **)&NDCacheEntry) == NX_SUCCESS)
+                {
+                    /* Add the next_hop in destination table. */
+                    status = _nx_icmpv6_dest_table_add(ip_ptr, dest_address, &dest_entry_ptr,
+                                                       next_hop_address, if_ptr -> nx_interface_ip_mtu_size,
+                                                       NX_WAIT_FOREVER, packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr);
+
+                    /* If the default router did not has a reachable ND_CACHE_ENTRY. Get the NDCacheEntry. */
+                    /*lint -e{644} suppress variable might not be initialized, since "NDCacheEntry" was initialized in _nxd_ipv6_route_lookup. */
+                    if ((status == NX_SUCCESS) && !NDCacheEntry)
+                    {
+                        NDCacheEntry = dest_entry_ptr -> nx_ipv6_destination_entry_nd_entry;
+                    }
+                }
+
+                /* Destination table add failed. */
+                if (status)
+                {
+
+                    /* Release the transmit packet. */
+                    _nx_packet_transmit_release(packet_ptr);
+
+                    /* Can't send it. */
+                    return;
+                }
+            }
+            /* Find a valid destination cache, set the nd cache and next hop address. */
+            else
+            {
+
+                /* Get the destination and next hop address. */
+                NDCacheEntry = dest_entry_ptr -> nx_ipv6_destination_entry_nd_entry;
+                COPY_IPV6_ADDRESS(dest_entry_ptr -> nx_ipv6_destination_entry_next_hop, next_hop_address);
+                NX_ASSERT(NDCacheEntry -> nx_nd_cache_nd_status != ND_CACHE_STATE_INVALID);
+            }
+
+            /* According RFC2461 ch 7.3.3, as long as the entry is valid and not in INCOMPLETE state,
+               the IP layer should use the cached link layer address.  */
+            if ((NDCacheEntry -> nx_nd_cache_nd_status >= ND_CACHE_STATE_REACHABLE) &&
+                (NDCacheEntry -> nx_nd_cache_nd_status <= ND_CACHE_STATE_PROBE))
+            {
+
+            UCHAR *mac_addr;
+
+                mac_addr = NDCacheEntry -> nx_nd_cache_mac_addr;
+
+                /* Assume we find the mac */
+                driver_request.nx_ip_driver_physical_address_msw = ((ULONG)mac_addr[0] << 8) | mac_addr[1];
+                driver_request.nx_ip_driver_physical_address_lsw =
+                    ((ULONG)mac_addr[2] << 24) | ((ULONG)mac_addr[3] << 16) | ((ULONG)mac_addr[4] << 8) | mac_addr[5];
+                driver_request.nx_ip_driver_interface            = if_ptr;
+
+                /* Check if path MTU Discovery is enabled first. */
+
+#ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
+
+                /* It is.  To know if we need to fragment this packet we need the path MTU for the packet
+                   destination.  */
+
+                /* If this destination has a non null next hop, we need to ascertain the next hop MTU.  */
+
+                /* Get the path MTU for the actual destination. */
+                next_hop_mtu = dest_entry_ptr -> nx_ipv6_destination_entry_path_mtu;
+
+
+                /* Find the next hop in the destination table. */
+                status = _nx_icmpv6_dest_table_find(ip_ptr, next_hop_address, &next_hop_dest_entry_ptr, 0, 0);
+
+                if (status == NX_SUCCESS)
+                {
+
+                    /* Now compare the destination path MTU with the next hop path MTU*/
+                    /*lint -e{644} suppress variable might not be initialized, since "next_hop_dest_entry_ptr" was initialized as long as status is NX_SUCCESS. */
+                    if ((next_hop_dest_entry_ptr -> nx_ipv6_destination_entry_path_mtu > 0) &&
+                        (next_hop_mtu > next_hop_dest_entry_ptr -> nx_ipv6_destination_entry_path_mtu))
+                    {
+
+                        /* Update the path mtu to reflect the next hop route. */
+                        next_hop_mtu = next_hop_dest_entry_ptr -> nx_ipv6_destination_entry_path_mtu;
+                    }
+                }
+
+#endif  /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
+
+                /* If the entry is in STALE state, move it to DELAY state. */
+                if (NDCacheEntry -> nx_nd_cache_nd_status == ND_CACHE_STATE_STALE)
+                {
+                    NDCacheEntry -> nx_nd_cache_nd_status = ND_CACHE_STATE_DELAY;
+
+                    /* Start the Delay first probe timer */
+                    NDCacheEntry -> nx_nd_cache_timer_tick = NX_DELAY_FIRST_PROBE_TIME;
+                }
+            }
+            else
+            {
+
+                /* No MAC address was found in our cache table.  Start the Neighbor Discovery (ND)
+                   process to get it. */
+
+                /* Ensure the current packet's queue next pointer to NULL */
+                packet_ptr -> nx_packet_queue_next = NX_NULL;
+
+                /* Determine if the queue is empty. */
+                if (NDCacheEntry -> nx_nd_cache_packet_waiting_head == NX_NULL)
+                {
+                    /* ICMPv6 is enabled */
+                    if (ip_ptr -> nx_ip_icmpv6_packet_process)
+                    {
+
+                        /* Queue up this packet */
+                        NDCacheEntry -> nx_nd_cache_packet_waiting_head = packet_ptr;
+                        NDCacheEntry -> nx_nd_cache_packet_waiting_tail = packet_ptr;
+                        NDCacheEntry -> nx_nd_cache_packet_waiting_queue_length = 1;
+
+                        /* Add debug information. */
+                        NX_PACKET_DEBUG(NX_PACKET_ND_WAITING_QUEUE, __LINE__, packet_ptr);
+
+                        /* Set the outgoing address and interface to the cache entry.  */
+                        NDCacheEntry -> nx_nd_cache_outgoing_address = packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr;
+                        NDCacheEntry -> nx_nd_cache_interface_ptr = if_ptr;
+
+                        /* Is this a new entry? */
+                        if (NDCacheEntry -> nx_nd_cache_nd_status == ND_CACHE_STATE_CREATED)
+                        {
+
+                            /* Start Neighbor discovery process by advancing to the incomplete state. */
+                            NDCacheEntry -> nx_nd_cache_nd_status = ND_CACHE_STATE_INCOMPLETE;
+                        }
+
+                        /* Note that the 2nd last parameter sendUnicast is set to Zero. In this case
+                           the last arg NDCacheEntry is not being used in _nx_icmpv6_send_ns. */
+                        _nx_icmpv6_send_ns(ip_ptr, next_hop_address,
+                                           1, packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr, 0, NDCacheEntry);
+
+                        NDCacheEntry -> nx_nd_cache_num_solicit = NX_MAX_MULTICAST_SOLICIT - 1;
+                        NDCacheEntry -> nx_nd_cache_timer_tick = ip_ptr -> nx_ipv6_retrans_timer_ticks;
+                    }
+                    else
+                    {
+
+                        _nx_packet_transmit_release(packet_ptr);
+#ifndef NX_DISABLE_IP_INFO
+
+                        /* Increment the IP transmit resource error count.  */
+                        ip_ptr -> nx_ip_transmit_resource_errors++;
+
+                        /* Increment the IP send packets dropped count.  */
+                        ip_ptr -> nx_ip_send_packets_dropped++;
+#endif
+                    }
+                    return;
+                }
+
+                /* The ND process already started.  Simply queue up this packet */
+                NDCacheEntry -> nx_nd_cache_packet_waiting_tail -> nx_packet_queue_next = packet_ptr;
+                NDCacheEntry -> nx_nd_cache_packet_waiting_tail = packet_ptr;
+                NDCacheEntry -> nx_nd_cache_packet_waiting_queue_length++;
+
+                /* Add debug information. */
+                NX_PACKET_DEBUG(NX_PACKET_ND_WAITING_QUEUE, __LINE__, packet_ptr);
+
+                /* Check if the number of packets enqueued exceeds the allowed number. */
+                if (NDCacheEntry -> nx_nd_cache_packet_waiting_queue_length > NX_ND_MAX_QUEUE_DEPTH)
+                {
+
+                    /* Yes, so delete the first packet. */
+                    remove_packet = NDCacheEntry -> nx_nd_cache_packet_waiting_head;
+
+                    NDCacheEntry -> nx_nd_cache_packet_waiting_head = remove_packet -> nx_packet_queue_next;
+
+                    /* Update the queued packet count for this cache entry. */
+                    NDCacheEntry -> nx_nd_cache_packet_waiting_queue_length--;
+
+                    _nx_packet_transmit_release(remove_packet);
+#ifndef NX_DISABLE_IP_INFO
+                    /* Increment the IP transmit resource error count.  */
+                    ip_ptr -> nx_ip_transmit_resource_errors++;
+
+                    /* Increment the IP send packets dropped count.  */
+                    ip_ptr -> nx_ip_send_packets_dropped++;
+#endif
+                }
+
+                return;
+            }
+        }
+    }
+    else
+    {
+
+        /* This IP instance does not require any IP-to-physical mapping.  */
+        /* Build the driver request.  */
+
+        driver_request.nx_ip_driver_physical_address_msw = 0;
+        driver_request.nx_ip_driver_physical_address_lsw = 0;
+        driver_request.nx_ip_driver_interface            = if_ptr;
+    }
+
+    /* Does the packet payload exceed next hop MTU?  */
+    if (packet_ptr -> nx_packet_length > next_hop_mtu)
+    {
+#ifndef NX_DISABLE_FRAGMENTATION
+#ifdef NX_IPSEC_ENABLE
+        /* Check the fragment status, transport mode SAs can not carry fragment, RFC 4301 page 66&88.  */
+        /*lint -e{774} suppress boolean always evaluates to True, since the value fragment can changed when NX_IPSEC_ENABLE is defined. */
+        if (fragment == NX_TRUE)
+        {
+#endif  /* NX_IPSEC_ENABLE */
+
+            /* Yes; ok to fragment the packet payload. */
+            _nx_ipv6_fragment_process(&driver_request, next_hop_mtu);
+#ifdef NX_IPSEC_ENABLE
+        }
+        else
+        {
+
+#ifndef NX_DISABLE_IP_INFO
+
+            /* Increment the IP send packets dropped count.  */
+            ip_ptr -> nx_ip_send_packets_dropped++;
+#endif
+            /* Just release the packet.  */
+            _nx_packet_transmit_release(packet_ptr);
+        }
+#endif  /* NX_IPSEC_ENABLE */
+
+#else   /* NX_DISABLE_FRAGMENTATION */
+
+#ifndef NX_DISABLE_IP_INFO
+        /* Increment the IP send packets dropped count.  */
+        ip_ptr -> nx_ip_send_packets_dropped++;
+#endif
+        /* Just release the packet.  */
+        _nx_packet_transmit_release(packet_ptr);
+#endif  /* NX_DISABLE_FRAGMENTATION */
+
+        /* This packet send is complete, just return.  */
+        return;
+    }
+
+    /* The packet requires no fragmentation. Proceed with sending the packet. */
+
+#ifndef NX_DISABLE_IP_INFO
+
+    /* Increment the IP packet sent count.  */
+    ip_ptr -> nx_ip_total_packets_sent++;
+
+    /* Increment the IP bytes sent count.  */
+    ip_ptr -> nx_ip_total_bytes_sent +=  packet_ptr -> nx_packet_length - (ULONG)sizeof(NX_IPV6_HEADER);
+#endif
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+    /* Driver entry must not be NULL. */
+    NX_ASSERT(if_ptr -> nx_interface_link_driver_entry != NX_NULL);
+
+    /* Send the IP packet out on the network via the attached driver.  */
+    (if_ptr -> nx_interface_link_driver_entry)(&driver_request);
+}
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_prefix_list_delete_entry.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_prefix_list_delete_entry.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_prefix_list_delete_entry.c	(revision 69)
@@ -0,0 +1,220 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_nd_cache.h"
+
+
+
+
+#ifdef FEATURE_NX_IPV6
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol version 6 Prefix Table (IPv6 prefix table)        */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_prefix_list_delete_entry                   PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function deletes an entry from the prefix list.                */
+/*                                                                        */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    entry                                 Entry to be deleted           */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    CHECK_IPV6_ADDRESS_SAME               Compare two IPv6 addresses    */
+/*    SET_SOLICITED_NODE_MULTICAST_ADDRESS  Get the solicited-node        */
+/*                                            multicast address           */
+/*    _nx_ipv6_multicast_leave              Leave an IPv6 mulcast group   */
+/*    [ipv6_address_change_notify]          User callback function        */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ipv6_prefix_list_delete           Delete a prefix entry.        */
+/*    _nx_ipv6_prefix_router_timer_tick     Router list timeout           */
+/*                                                                        */
+/*  NOTE                                                                  */
+/*                                                                        */
+/*    This function cannot be called from ISR.                            */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID _nx_ipv6_prefix_list_delete_entry(NX_IP *ip_ptr, NX_IPV6_PREFIX_ENTRY *entry)
+{
+
+UINT              i;
+ULONG             address_prefix[4];
+NXD_IPV6_ADDRESS *interface_ipv6_address_prev, *interface_ipv6_address;
+ULONG             multicast_address[4];
+#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
+UINT              ipv6_addr_index;
+#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
+
+    /* Invalidate the interface IP address if we obtained the
+       interface IP address based on the prefix information. */
+
+    /* Search through each physical interface for a match. */
+    for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
+    {
+
+        /* Get a pointer to the first address in the interface list. */
+        interface_ipv6_address = ip_ptr -> nx_ip_interface[i].nxd_interface_ipv6_address_list_head;
+        interface_ipv6_address_prev = NX_NULL;
+
+        /* Search the address list for a match. */
+        while (interface_ipv6_address)
+        {
+
+            /* Is this interface address valid? */
+            if (interface_ipv6_address -> nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_UNKNOWN &&
+                interface_ipv6_address -> nxd_ipv6_address_ConfigurationMethod == NX_IPV6_ADDRESS_BASED_ON_INTERFACE)
+            {
+
+                /* Yes.  Extract the prefix to match on. The prefix length is 64 bits. */
+                address_prefix[0] = interface_ipv6_address -> nxd_ipv6_address[0];
+                address_prefix[1] = interface_ipv6_address -> nxd_ipv6_address[1];
+                address_prefix[2] = 0;
+                address_prefix[3] = 0;
+
+                /* Do we have a match?  */
+                if (CHECK_IPV6_ADDRESSES_SAME(address_prefix, entry -> nx_ipv6_prefix_entry_network_address))
+                {
+
+                    /* Yes, invalidate this address.  */
+                    interface_ipv6_address -> nxd_ipv6_address_valid = NX_FALSE;
+                    interface_ipv6_address -> nxd_ipv6_address_state = NX_IPV6_ADDR_STATE_UNKNOWN;
+
+                    interface_ipv6_address -> nxd_ipv6_address_ConfigurationMethod = NX_IPV6_ADDRESS_NOT_CONFIGURED;
+
+#ifndef NX_DISABLE_IPV6_DAD
+                    interface_ipv6_address -> nxd_ipv6_address_DupAddrDetectTransmit = 0;
+#endif /* NX_DISABLE_IPV6_DAD */
+
+                    /* Update the list. */
+                    if (interface_ipv6_address_prev == NX_NULL)
+                    {
+                        ip_ptr -> nx_ip_interface[i].nxd_interface_ipv6_address_list_head = interface_ipv6_address -> nxd_ipv6_address_next;
+                    }
+                    else
+                    {
+                        interface_ipv6_address_prev -> nxd_ipv6_address_next = interface_ipv6_address -> nxd_ipv6_address_next;
+                    }
+
+                    /* Delete the associated multicast address. */
+                    SET_SOLICITED_NODE_MULTICAST_ADDRESS(multicast_address, interface_ipv6_address -> nxd_ipv6_address);
+
+                    _nx_ipv6_multicast_leave(ip_ptr, &multicast_address[0], interface_ipv6_address -> nxd_ipv6_address_attached);
+
+#ifdef NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY
+                    /* If the address change notify callback is set, invoke the callback function. */
+                    if (ip_ptr -> nx_ipv6_address_change_notify)
+                    {
+                        ipv6_addr_index = (ULONG)interface_ipv6_address -> nxd_ipv6_address_index;
+                        ip_ptr -> nx_ipv6_address_change_notify(ip_ptr, NX_IPV6_ADDRESS_LIFETIME_EXPIRED, i, ipv6_addr_index,
+                                                                &interface_ipv6_address -> nxd_ipv6_address[0]);
+                    }
+#endif /* NX_ENABLE_IPV6_ADDRESS_CHANGE_NOTIFY */
+
+                    /* Clear the address at last. */
+                    SET_UNSPECIFIED_ADDRESS(interface_ipv6_address -> nxd_ipv6_address);
+
+                    /* Address for this interface is found. Just break. */
+                    break;
+                }
+            }
+
+            /* Set the previous address. */
+            interface_ipv6_address_prev = interface_ipv6_address;
+
+            /* Get the next address. */
+            interface_ipv6_address = interface_ipv6_address -> nxd_ipv6_address_next;
+        } /* while (interface_ipv6_address) */
+    } /* for(i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++) */
+
+    /* Unlink the previous node, if it exists. */
+    if (entry -> nx_ipv6_prefix_entry_prev == NX_NULL)
+    {
+        ip_ptr -> nx_ipv6_prefix_list_ptr = entry -> nx_ipv6_prefix_entry_next;
+    }
+    else
+    {
+        entry -> nx_ipv6_prefix_entry_prev -> nx_ipv6_prefix_entry_next = entry -> nx_ipv6_prefix_entry_next;
+    }
+
+    /* Unlink the next node if it exists. */
+    if (entry -> nx_ipv6_prefix_entry_next)
+    {
+        entry -> nx_ipv6_prefix_entry_next -> nx_ipv6_prefix_entry_prev = entry -> nx_ipv6_prefix_entry_prev;
+    }
+
+    /* Clean up this entry. */
+    entry -> nx_ipv6_prefix_entry_next = NX_NULL;
+    entry -> nx_ipv6_prefix_entry_prev = NX_NULL;
+
+    /* Put entry onto the free list.*/
+    if (ip_ptr -> nx_ipv6_prefix_entry_free_list == NX_NULL)
+    {
+        /* Free list is empty.  Set entry to be the first on the list. */
+        ip_ptr -> nx_ipv6_prefix_entry_free_list = entry;
+    }
+    else
+    {
+
+        /* Free list is not empty.  Insert the entry to the head of the list. */
+        ip_ptr -> nx_ipv6_prefix_entry_free_list -> nx_ipv6_prefix_entry_prev = entry;
+        entry -> nx_ipv6_prefix_entry_next = ip_ptr -> nx_ipv6_prefix_entry_free_list;
+        ip_ptr -> nx_ipv6_prefix_entry_free_list = entry;
+    }
+
+    /* All done. Return. */
+    return;
+}
+
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_process_fragment_option.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_process_fragment_option.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_process_fragment_option.c	(revision 69)
@@ -0,0 +1,224 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_ipv6.h"
+#include "nx_packet.h"
+#include "nx_icmpv6.h"
+
+#if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_FRAGMENTATION)
+
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_process_fragment_option                    PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function processes the IPv6 Fragmentation Option header.       */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to packet to process  */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS                            Successful completion         */
+/*    NX_CONTINUE                           Continue processing           */
+/*    NX_OPTION_HEADER_ERROR                Error with fragment option    */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ip_dispatch_process               Process IPv6 optional headers */
+/*    NX_ICMPV6_SEND_PARAMETER_PROBLEM      Report IPv6 errors via ICMP   */
+/*                                            message                     */
+/*    tx_event_flags_set                    Wake up the IP helper thread  */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ip_dispatch_process               Process IPv6 optional header  */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
+/*                                            packet length verification, */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT _nx_ipv6_process_fragment_option(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
+{
+
+TX_INTERRUPT_SAVE_AREA
+NX_IPV6_HEADER_FRAGMENT_OPTION *fragment_option;
+
+
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+#ifndef NX_DISABLE_IP_INFO
+
+    /* Increment the IP receive fragments count */
+    ip_ptr -> nx_ip_total_fragments_received++;
+
+#endif /* NX_DISABLE_IP_INFO */
+
+    /* If fragmentation is not enabled, we drop this packet. */
+    if (!ip_ptr -> nx_ip_fragment_assembly)
+    {
+        return(NX_OPTION_HEADER_ERROR);
+    }
+
+    /* Check packet length is at least sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION). */
+    if (packet_ptr -> nx_packet_length < sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION))
+    {
+        return(NX_OPTION_HEADER_ERROR);
+    }
+
+    /* Set a pointer to the starting of the fragment option. */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    fragment_option = (NX_IPV6_HEADER_FRAGMENT_OPTION *)packet_ptr -> nx_packet_prepend_ptr;
+
+    /* Byte swap the offset_flag.  The identification field is only used for checking matches.
+       The absolute value of the Id is not used in arithmatic operations.  Therefore there is
+       need to byte-swap this field. */
+    NX_CHANGE_USHORT_ENDIAN(fragment_option -> nx_ipv6_header_fragment_option_offset_flag);
+
+    /* Check whether or not the payload size is not multiple of 8 bytes if the
+       M bit is set. */
+    if (fragment_option -> nx_ipv6_header_fragment_option_offset_flag & 0x0001) /* M bit is set */
+    {
+
+    NX_IPV6_HEADER *ip_header;
+    ULONG           payload_length;
+
+        /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        ip_header = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_ip_header;
+
+        payload_length = ip_header -> nx_ip_header_word_1 >> 16;
+
+        /* If not multiple of 8 bytes... */
+        if ((payload_length & 0xFFF8) != payload_length)
+        {
+
+            /* Return the option header error status and abort. */
+
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+
+            /* Cover offset flag field. */
+            NX_CHANGE_USHORT_ENDIAN(fragment_option -> nx_ipv6_header_fragment_option_offset_flag);
+
+            /*lint -e{835} -e{845} suppress operating on zero. */
+            NX_ICMPV6_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, 0, 4);
+#endif
+            return(NX_OPTION_HEADER_ERROR);
+        }
+    }
+    /* M bit is clear: This is the last (tail) packet fragment. */
+    else if ((fragment_option -> nx_ipv6_header_fragment_option_offset_flag & 0xFFF8) == 0)
+    {
+
+        /* Continue processing. */
+        return(NX_CONTINUE);
+    }
+
+    /* Payload size cannot exceeding 65535. */
+    if (((fragment_option -> nx_ipv6_header_fragment_option_offset_flag & 0xFFF8) + packet_ptr -> nx_packet_length -
+         sizeof(NX_IPV6_HEADER_FRAGMENT_OPTION)) > 65535)
+    {
+
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+
+        /* Cover offset flag field. */
+        NX_CHANGE_USHORT_ENDIAN(fragment_option -> nx_ipv6_header_fragment_option_offset_flag);
+
+        /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+        /*lint -e{835} -e{845} suppress operating on zero. */
+        NX_ICMPV6_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, 0,
+                                         (ULONG)((packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_ip_header) + 2));
+#endif /* NX_DISABLE_ICMPV6_ERROR_MESSAGE */
+
+        /* Return an Option header error status. */
+        return(NX_OPTION_HEADER_ERROR);
+    }
+
+    /* Disable interrupt */
+    TX_DISABLE
+
+    /* In IPv6 IP fragmentation is required. */
+
+    /* Determine if the queue is empty.  */
+    if (ip_ptr -> nx_ip_received_fragment_head)
+    {
+
+        /* Raw receive queue is not empty, add this packet to the end of the queue.  */
+        (ip_ptr -> nx_ip_received_fragment_tail) -> nx_packet_queue_next =  packet_ptr;
+        packet_ptr -> nx_packet_queue_next =  NX_NULL;
+        ip_ptr -> nx_ip_received_fragment_tail =  packet_ptr;
+    }
+    else
+    {
+
+        /* Raw receive queue is empty.  Just set the head and tail pointers
+           to point to this packet.  */
+        ip_ptr -> nx_ip_received_fragment_head =  packet_ptr;
+        ip_ptr -> nx_ip_received_fragment_tail =  packet_ptr;
+        packet_ptr -> nx_packet_queue_next     =  NX_NULL;
+    }
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(NX_PACKET_IP_FRAGMENT_QUEUE, __LINE__, packet_ptr);
+
+    /* Restore interrupts.  */
+    TX_RESTORE
+
+#ifndef NX_FRAGMENT_IMMEDIATE_ASSEMBLY
+    /* Wakeup IP helper thread to process the IP fragment re-assembly.  */
+    tx_event_flags_set(&(ip_ptr -> nx_ip_events), NX_IP_UNFRAG_EVENT, TX_OR);
+#else
+    /* Process the IP fragment reassemble.  */
+    (ip_ptr -> nx_ip_fragment_assembly)(ip_ptr);
+#endif /* NX_FRAGMENT_IMMEDIATE_ASSEMBLY */
+
+    return(NX_SUCCESS);
+}
+
+#endif /* FEATURE_NX_IPV6 && NX_DISABLE_FRAGMENTATION*/
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_process_hop_by_hop_option.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_process_hop_by_hop_option.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_process_hop_by_hop_option.c	(revision 69)
@@ -0,0 +1,193 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_icmpv6.h"
+
+#ifdef FEATURE_NX_IPV6
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_process_hop_by_hop_option                  PORTABLE C      */
+/*                                                           6.1.3        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function processes the Hop by Hop and the Destination headers. */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to packet to process  */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS                            Successful completion         */
+/*    NX_OPTION_HEADER_ERROR                Error parsing packet options  */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ipv6_option_error                Handle errors in IPv6 option   */
+/*                                                                        */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ipv6_dispatch_process            Process IPv6 optional header   */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  12-31-2020     Yuxin Zhou               Modified comment(s), improved */
+/*                                            buffer read overflow check, */
+/*                                            resulting in version 6.1.3  */
+/*                                                                        */
+/**************************************************************************/
+UINT _nx_ipv6_process_hop_by_hop_option(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
+{
+
+INT                        header_length;
+UINT                       offset_base, offset;
+UINT                       rv;
+NX_IPV6_HOP_BY_HOP_OPTION *option;
+
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+    /*  Make sure there's no OOB when reading Hdr Ext Len from the packet buffer. */
+    if ((UINT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) < 2)
+    {
+
+        /* return an error code. */
+        return(NX_OPTION_HEADER_ERROR);
+    }
+
+    /* Read the Hdr Ext Len field. */
+    header_length = *(packet_ptr -> nx_packet_prepend_ptr + 1);
+
+    /* Calculate the the true header length: (n + 1) * 8 */
+    header_length = (header_length + 1) << 3;
+
+    /* The 1st option starts from the 3rd byte. */
+    offset = 2;
+
+    /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+    /*lint -e{737} suppress loss of sign, since nx_packet_append_ptr is assumed to be larger than nx_packet_ip_header. */
+    offset_base = (UINT)((ULONG)(packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_ip_header) - (ULONG)sizeof(NX_IPV6_HEADER));
+    header_length = header_length - (INT)offset;
+
+    /* Sanity check; does the header length data go past the end of the end of the packet buffer? */
+    /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+    if ((UINT)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr) <
+        ((UINT)header_length + offset))
+    {
+
+        /* Yes, handle the error as indicated by the option type 2 msb's. */
+        /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        option = (NX_IPV6_HOP_BY_HOP_OPTION *)(packet_ptr -> nx_packet_prepend_ptr + offset);
+
+        _nx_ipv6_option_error(ip_ptr, packet_ptr, option -> nx_ipv6_hop_by_hop_option_type, offset_base + offset);
+        return(NX_OPTION_HEADER_ERROR);
+    }
+
+    while (header_length > 0)
+    {
+
+        /* Get a pointer to the options. */
+        /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        option = (NX_IPV6_HOP_BY_HOP_OPTION *)(packet_ptr -> nx_packet_prepend_ptr + offset);
+
+        switch (option -> nx_ipv6_hop_by_hop_option_type)
+        {
+
+        case 0:
+
+            /* Pad1 option.  This option indicates the size of the padding is one.
+               So we skip one byte. */
+            offset++;
+            header_length--;
+            break;
+
+        case 1:
+
+            /* PadN option. Skip N+2 bytes. */
+            offset += ((UINT)(option -> nx_ipv6_hop_by_hop_length) + 2);
+            header_length -= ((INT)(option -> nx_ipv6_hop_by_hop_length) + 2);
+            break;
+
+#ifdef NX_ENABLE_THREAD
+        case 109:
+
+            /* RFC 7731.  */
+
+            /* Skip N+2 bytes.  */
+            offset += ((UINT)(option -> nx_ipv6_hop_by_hop_length) + 2);
+            header_length -= ((INT)(option -> nx_ipv6_hop_by_hop_length) + 2);
+            break;
+#endif /* NX_ENABLE_THREAD  */
+
+        default:
+
+            /* Unknown option.  */
+            rv = _nx_ipv6_option_error(ip_ptr, packet_ptr, option -> nx_ipv6_hop_by_hop_option_type, offset_base + offset);
+
+            /* If no errors, just skip this option and move onto the next option.*/
+            if (rv == NX_SUCCESS)
+            {
+
+                /* Skip this option and continue processing the rest of the header. */
+                offset += ((UINT)(option -> nx_ipv6_hop_by_hop_length) + 2);
+                header_length -= ((INT)(option -> nx_ipv6_hop_by_hop_length) + 2);
+                break;
+            }
+            else
+            {
+
+                /* Return value indicates an error status: we need to drop the entire packet. */
+                return(rv); /* Drop this packet. */
+            }
+        }
+    }
+
+    /* Successful processing of option header. */
+    return(NX_SUCCESS);
+}
+
+#endif /*  FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_process_routing_option.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_process_routing_option.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_process_routing_option.c	(revision 69)
@@ -0,0 +1,127 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_icmpv6.h"
+
+#ifdef FEATURE_NX_IPV6
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_process_routing_option                     PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function processes the Routing Option header.                  */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    packet_ptr                            Pointer to packet to process  */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS                             Successful completion        */
+/*    NX_OPTION_HEADER_ERROR                 Error parsing router option  */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ipv6_packet_receive                                             */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s), improved */
+/*                                            packet length verification, */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT _nx_ipv6_process_routing_option(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
+{
+
+NX_IPV6_HEADER_ROUTING_OPTION *option;
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+UINT                           base_offset;
+#endif
+
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+    /* Check packet length is at least sizeof(NX_IPV6_HEADER_ROUTING_OPTION). */
+    if (packet_ptr -> nx_packet_length < sizeof(NX_IPV6_HEADER_ROUTING_OPTION))
+    {
+        return(NX_OPTION_HEADER_ERROR);
+    }
+
+    /* Set a pointer to the routing header. */
+    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    option = (NX_IPV6_HEADER_ROUTING_OPTION *)(packet_ptr -> nx_packet_prepend_ptr);
+
+    if (option -> nx_ipv6_header_routing_option_segments_left == 0)
+    {
+        /* Skip the rest of the routing header and continue processing this packet. */
+        return(NX_SUCCESS);
+    }
+
+    /* According to RFC 5095, Routing Header 0 (described in RFC 2460) has been
+       deprecated.  Therefore discard the packet that has segments left, and send
+       an ICMP Parameter Problem if such feature is enabled. */
+
+#ifndef NX_DISABLE_ICMPV6_ERROR_MESSAGE
+
+    /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+    base_offset = (UINT)(packet_ptr -> nx_packet_prepend_ptr - packet_ptr -> nx_packet_ip_header);
+
+    /*lint -e{835} -e{845} suppress operating on zero. */
+    NX_ICMPV6_SEND_PARAMETER_PROBLEM(ip_ptr, packet_ptr, 0, base_offset + 2);
+#else
+    NX_PARAMETER_NOT_USED(ip_ptr);
+#endif
+
+    /* Return error status, so the caller knows to free the packet. */
+    return(NX_OPTION_HEADER_ERROR);
+}
+
+
+#endif /*  FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_util.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_util.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_ipv6_util.c	(revision 69)
@@ -0,0 +1,948 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+#include "tx_api.h"
+#include "nx_api.h"
+#include "nx_ipv6.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    CHECK_IP_ADDRESSES_BY_PREFIX                        PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function checks whether or not two IPv6 addresses are the      */
+/*    same by prefix length                                               */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_addr1                              Two 128-bit IPv6 addresses to */
+/*    ip_addr2                              be checked.                   */
+/*    prefix_len                            Prefix length                 */
+/*                                                                        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    0                                     The addresses are different.  */
+/*    1                                     The addresses are the same.   */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+INT CHECK_IP_ADDRESSES_BY_PREFIX(ULONG *ip_addr1, ULONG *ip_addr2,
+                                 ULONG prefix_len)
+{
+
+
+ULONG high_prefix; /* Num of ULONG in prefix. */
+ULONG low_prefix;  /* Remaining bits in prefix after high prefix. */
+ULONG mask;
+
+
+    /* Get number of ULONGs that can fit in the specified prefix length. */
+    high_prefix  = prefix_len >> 5;
+
+    /* Get the remaining bits in prefix length. */
+    low_prefix  = prefix_len &  0x1f;
+
+    /* Would the prefix length have 1 or more ULONGs? */
+    if (high_prefix)
+    {
+
+        /* Yes; compare that number of ULONGS (in bytes) in each input address. */
+        if (memcmp(ip_addr1, ip_addr2, high_prefix << 2))
+        {
+            /* A nonzero result indicates a mismatch. */
+            return(0);
+        }
+    }
+
+    /* Are there any bits to compare after the high order bits? */
+    if (low_prefix)
+    {
+
+        /* Compare these bits between the two addresses, after masking out the upper ULONGs. */
+        mask = ((0xFFFFFFFF) << (32 - low_prefix)) & 0xFFFFFFFF;
+
+        if ((ip_addr1[high_prefix] ^ ip_addr2[high_prefix]) & mask)
+        {
+            return(0);
+        }
+    }
+
+    return(1);
+}
+
+
+
+/*
+ * Developers may define "NX_IPV6_UTIL_INLINE to make the following functions
+ * inline.  Inline functions improve execution speed.  However they make
+ * code size larger.
+ */
+
+#ifndef NX_IPV6_UTIL_INLINE
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    CHECK_IPV6_ADDRESSES_SAME                           PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function checks whether or not two IPv6 addresses are the      */
+/*    same.                                                               */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_addr1                              Two 128-bit IPv6 addresses to */
+/*    ip_addr2                              be checked.                   */
+/*                                                                        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    0                                     The addresses are different.  */
+/*    1                                     The addresses are the same.   */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+INT CHECK_IPV6_ADDRESSES_SAME(ULONG *ip_addr1, ULONG *ip_addr2)
+{
+#ifdef FEATURE_NX_IPV6
+    return(ip_addr1[0] == ip_addr2[0] &&
+           ip_addr1[1] == ip_addr2[1] &&
+           ip_addr1[2] == ip_addr2[2] &&
+           ip_addr1[3] == ip_addr2[3]);
+#else /* FEATURE_NX_IPV6 */
+    NX_PARAMETER_NOT_USED(ip_addr1);
+    NX_PARAMETER_NOT_USED(ip_addr2);
+
+    return(0);
+#endif /* FEATURE_NX_IPV6 */
+}
+
+#ifdef NX_IPSEC_ENABLE
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    CHECK_IPV6_ADDRESS_RANGE                            PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function checks the IPv6 address whether or not between        */
+/*    two IPv6 addresses.                                                 */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_addr_start                         IPv6 address start            */
+/*    ip_addr_end                           Ipv6 address end              */
+/*    ip_addr                               The 128-bit IPv6 address to.  */
+/*                                               be checked               */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    0                                    Not between two IPv6 address.  */
+/*    1                                    Between two IPv6 address.      */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+INT CHECK_IPV6_ADDRESS_RANGE(ULONG *ip_addr_start, ULONG *ip_addr_end, ULONG *ip_addr)
+{
+#ifdef FEATURE_NX_IPV6
+INT ip_addr_cmp1 = 0, ip_addr_cmp2 = 0;
+
+    /* Check the IP address whether or not bigger than IP address start.  */
+    /* compare the first 32 bit.  */
+    if (ip_addr_start[0] < ip_addr[0])
+    {
+        ip_addr_cmp1 = 1;
+    }
+    else if (ip_addr_start[0] == ip_addr[0])
+    {
+
+        /* compare the second 32 bit.  */
+        if (ip_addr_start[1] < ip_addr[1])
+        {
+            ip_addr_cmp1 = 1;
+        }
+        else if (ip_addr_start[1] == ip_addr[1])
+        {
+            /* compare the third 32 bit.  */
+            if (ip_addr_start[2] < ip_addr[2])
+            {
+                ip_addr_cmp1 = 1;
+            }
+            else if (ip_addr_start[2] == ip_addr[2])
+            {
+                /* compare the forth 32 bit.  */
+                if (ip_addr_start[3] <= ip_addr[3])
+                {
+                    ip_addr_cmp1 = 1;
+                }
+            }
+        }
+    }
+
+    /* Check the IP address whether or not smaller than IP address end.  */
+    /* compare the first 32 bit.  */
+    if (ip_addr[0] < ip_addr_end[0])
+    {
+        ip_addr_cmp2 = 1;
+    }
+    else if (ip_addr[0] == ip_addr_end[0])
+    {
+        /* compare the second 32 bit.  */
+        if (ip_addr[1] < ip_addr_end[1])
+        {
+            ip_addr_cmp2 = 1;
+        }
+        else if (ip_addr[1] == ip_addr_end[1])
+        {
+            /* compare the second 32 bit.  */
+            if (ip_addr[2] < ip_addr_end[2])
+            {
+                ip_addr_cmp2 = 1;
+            }
+            else if (ip_addr[2] == ip_addr_end[2])
+            {
+                /* compare the second 32 bit.  */
+                if (ip_addr[3] <= ip_addr_end[3])
+                {
+                    ip_addr_cmp2 = 1;
+                }
+            }
+        }
+    }
+    if ((ip_addr_cmp1 == 1) && (ip_addr_cmp2 == 1))
+    {
+        return(1);
+    }
+    else
+    {
+        return(0);
+    }
+#else /* FEATURE_NX_IPV6 */
+    NX_PARAMETER_NOT_USED(ip_addr_start);
+    NX_PARAMETER_NOT_USED(ip_addr_end);
+    NX_PARAMETER_NOT_USED(ip_addr);
+
+    return(0);
+#endif /* FEATURE_NX_IPV6 */
+}
+#endif /* NX_IPSEC_ENABLE */
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    CHECK_UNSPECIFIED_ADDRESS                           PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function checks whether or not an address is unspecified (::)  */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_address                            The 128-bit IPv6 address to   */
+/*                                          be checked.  The address is   */
+/*                                          in host byte order.           */
+/*                                                                        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                0:The address is not zero     */
+/*                                          1:The address is unspecified  */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+INT CHECK_UNSPECIFIED_ADDRESS(ULONG *ip_addr)
+{
+#ifdef FEATURE_NX_IPV6
+    return(!(ip_addr[0] || ip_addr[1] || ip_addr[2] || ip_addr[3]));
+#else
+    NX_PARAMETER_NOT_USED(ip_addr);
+    return(0);
+#endif
+}
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    SET_UNSPECIFIED_ADDRESS                             PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function marks an IPv6 address as unnspecified (::).           */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_address                            The 128-bit IPv6 address to   */
+/*                                          be set.                       */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+void SET_UNSPECIFIED_ADDRESS(ULONG *ip_addr)
+{
+#ifdef FEATURE_NX_IPV6
+    ip_addr[0] = 0;
+    ip_addr[1] = 0;
+    ip_addr[2] = 0;
+    ip_addr[3] = 0;
+#else
+    NX_PARAMETER_NOT_USED(ip_addr);
+#endif /* FEATURE_NX_IPV6 */
+}
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    COPY_IPV6_ADDRESS                                   PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function makes a copy of an IPv6 address.                      */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    copy_from                             The 128-bit IPv6 address to   */
+/*                                          be copied.                    */
+/*    copy_to                               The 128-bit IPv6 address to   */
+/*                                          be filled in.                 */
+/*                                                                        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+void COPY_IPV6_ADDRESS(ULONG *copy_from, ULONG *copy_to)
+{
+#ifdef FEATURE_NX_IPV6
+    copy_to[0] = copy_from[0];
+    copy_to[1] = copy_from[1];
+    copy_to[2] = copy_from[2];
+    copy_to[3] = copy_from[3];
+#else
+    NX_PARAMETER_NOT_USED(copy_from);
+    NX_PARAMETER_NOT_USED(copy_to);
+#endif /* FEATURE_NX_IPV6 */
+}
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    COPY_NXD_ADDRESS                                    PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function makes a copy of an IP address from one NXD_ADDRESS    */
+/*    data to another NXD_ADDRESS, including the version.  Note that      */
+/*    filling in the nxd_ip_address.v6[0] address also suffices for       */
+/*    filling in the nxd_ip_address.v4 IP address field if the input      */
+/*    NXD_ADDRESS argument is for an IPv4 address.                        */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    copy_from                             The NXD address control block */
+/*                                          to be copied.                 */
+/*    copy_to                               The NXD address control block */
+/*                                          to copy to.                   */
+/*                                                                        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+
+void COPY_NXD_ADDRESS(NXD_ADDRESS *copy_from, NXD_ADDRESS  *copy_to)
+{
+#ifdef FEATURE_NX_IPV6
+    copy_to -> nxd_ip_version       = copy_from -> nxd_ip_version;
+    copy_to -> nxd_ip_address.v6[0] = copy_from -> nxd_ip_address.v6[0];
+    copy_to -> nxd_ip_address.v6[1] = copy_from -> nxd_ip_address.v6[1];
+    copy_to -> nxd_ip_address.v6[2] = copy_from -> nxd_ip_address.v6[2];
+    copy_to -> nxd_ip_address.v6[3] = copy_from -> nxd_ip_address.v6[3];
+#else
+    NX_PARAMETER_NOT_USED(copy_from);
+    NX_PARAMETER_NOT_USED(copy_to);
+#endif /* FEATURE_NX_IPV6 */
+}
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    SET_SOLICITED_NODE_MULTICAST_ADDRESS                PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function sets the solicited-node multicast address based on    */
+/*    a unicast IPv6 address.                                             */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    address                               Storage space of an IPv6      */
+/*                                          solicited-node multicast      */
+/*                                          address to be created.        */
+/*    unicast_address                       The unicast address to use    */
+/*                                          when creating the solicited-  */
+/*                                          node multicast address.       */
+/*                                                                        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+void SET_SOLICITED_NODE_MULTICAST_ADDRESS(ULONG *address,
+                                          ULONG *unicast_address)
+{
+#ifdef FEATURE_NX_IPV6
+    address[0] = (ULONG)0xFF020000;
+    address[1] = (ULONG)0;
+    address[2] = (ULONG)0x00000001;
+    address[3] = (ULONG)(0xFF000000 | unicast_address[3]);
+#else
+    NX_PARAMETER_NOT_USED(address);
+    NX_PARAMETER_NOT_USED(unicast_address);
+#endif /* FEATURE_NX_IPV6 */
+}
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    CHECK_ALL_ROUTER_MCAST_ADDRESS                      PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function checks whether or not an address is an all-router     */
+/*    multicast address.                                                  */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    address                               The 128-bit IPv6 address to   */
+/*                                          be checked.  The address is   */
+/*                                          in host byte order.           */
+/*                                                                        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    0                                     The address is not an all-    */
+/*                                          router mullticast address.    */
+/*    1                                     The address is an all-router  */
+/*                                          multicast address.            */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+INT CHECK_ALL_ROUTER_MCAST_ADDRESS(ULONG *address)
+{
+#ifdef FEATURE_NX_IPV6
+
+    return(address[0] == (ULONG)0xFF020000 &&
+           address[1] == (ULONG)0 &&
+           address[2] == (ULONG)0 &&
+           address[3] == (ULONG)0x00000002);
+
+#else /* !FEATURE_NX_IPV6 */
+    NX_PARAMETER_NOT_USED(address);
+
+    return(0);
+#endif /* FEATURE_NX_IPV6 */
+}
+
+#endif /* NX_IPV6_UTIL_INLINE */
+
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    CHECK_IPV6_SOLICITED_NODE_MCAST_ADDRESS             PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function checks whether or not an address is a solicited-node  */
+/*    multicast address.                                                  */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    dest_ip                               The 128-bit IPv6 address to   */
+/*                                          be checked.  The address is   */
+/*                                          in host byte order.           */
+/*    myip                                  The 128-bit local interface   */
+/*                                          address, in host byte order.  */
+/*                                                                        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    0                                     The address is not solicited- */
+/*                                          node multicast address.       */
+/*    1                                     The address is solicited-node */
+/*                                          multicast address.            */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+INT CHECK_IPV6_SOLICITED_NODE_MCAST_ADDRESS(ULONG *dest_ip, ULONG *myip)
+{
+#ifdef FEATURE_NX_IPV6
+
+INT isMulticast = 0;
+
+    if ((dest_ip[0] == (ULONG)0xFF020000) && (dest_ip[1] == (ULONG)0x0) &&
+        (dest_ip[2] == (ULONG)0x00000001) &&
+        (dest_ip[3] == ((myip[3] & (ULONG)0x00FFFFFF) | (ULONG)0xFF000000)))
+    {
+        isMulticast = 1;
+    }
+    else if ((dest_ip[0] == (ULONG)0xFF020000) &&
+             (dest_ip[1] == (ULONG)0x0) &&
+             (dest_ip[2] == (ULONG)0x0) &&
+             ((dest_ip[3] == (ULONG)0x00000001) || (dest_ip[3] == (ULONG)0x00010002)))
+    {
+        isMulticast = 1;
+    }
+#ifdef NX_ENABLE_THREAD
+    else if ((dest_ip[0] == (ULONG)0xFF030000) &&
+             (dest_ip[1] == (ULONG)0x0) &&
+             (dest_ip[2] == (ULONG)0x0) &&
+             ((dest_ip[3] == (ULONG)0x00000001)))     /* Realm-Local All nodes multicast address.     */
+    {
+        isMulticast = 1;
+    }
+#endif /* NX_ENABLE_THREAD  */
+    else if ((dest_ip[0] == (ULONG)0xFF050000) &&
+             (dest_ip[1] == (ULONG)0x0) &&
+             (dest_ip[2] == (ULONG)0x0) &&
+             (dest_ip[3] == (ULONG)0x00010003))
+    {
+        isMulticast = 1;
+    }
+    return(isMulticast);
+#else
+    NX_PARAMETER_NOT_USED(dest_ip);
+    NX_PARAMETER_NOT_USED(myip);
+
+    return(0);
+#endif /* FEATURE_NX_IPV6 */
+}
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    IPv6_Address_Type                                   PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function checks the type of an IP address.                     */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_address                            The 128-bit IPv6 address to   */
+/*                                          be checked.  The address is   */
+/*                                          in host byte order.           */
+/*                                                                        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    Address type                          A bit mask indicates the      */
+/*                                          of the IPv6 address.          */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+ULONG IPv6_Address_Type(ULONG *ip_address)
+{
+
+#ifdef FEATURE_NX_IPV6
+ULONG ret;
+
+/* Validate address type.
+   ::/128                  Unspecified address
+   ::1/128                 Loopback
+   FF00::/8                Multicast
+   FE80::/10               Link-local
+   FEC0::/10               Global (Its use as Site-local has been deprecated (RFC 4291)
+   Everything else         Global
+ */
+ULONG tmp;
+
+    /* Is this multicast? */
+    if ((ip_address[0] & (ULONG)0xFF000000) == (ULONG)0xFF000000)
+    {
+        /* Yes. */
+        ret = IPV6_ADDRESS_MULTICAST;
+
+        /* Determine type of multicast... */
+        if (((ip_address[0] == (ULONG)0xFF010000) ||
+             (ip_address[0] == (ULONG)0xFF020000)) &&
+            (ip_address[1] == (ULONG)0) &&
+            (ip_address[2] == (ULONG)0) &&
+            (ip_address[3] == (ULONG)1))
+        {
+            return(ret | IPV6_ALL_NODE_MCAST);
+        }
+
+
+        if ((ip_address[0] == (ULONG)0xFF050000) &&     /* All DHCPv6 relay and server hosts */
+            (ip_address[1] == (ULONG)0) &&
+            (ip_address[2] == (ULONG)0) &&
+            (ip_address[3] == (ULONG)0x00010003))
+        {
+            return(ret | IPV6_ALL_NODE_MCAST);
+        }
+
+        if (((ip_address[0] == (ULONG)0xFF010000) ||
+             (ip_address[0] == (ULONG)0xFF020000) ||
+             (ip_address[0] == (ULONG)0xFF050000)) &&
+            (ip_address[1] == (ULONG)0) &&
+            (ip_address[2] == (ULONG)0) &&
+            (ip_address[3] == (ULONG)2))
+        {
+            return(ret | IPV6_ALL_ROUTER_MCAST);
+        }
+
+        if ((ip_address[0] == (ULONG)0xFF020000) &&
+            (ip_address[1] == (ULONG)0) &&
+            (ip_address[2] == (ULONG)1) &&
+            (ip_address[3] >= (ULONG)0xFF000000))
+        {
+            return(ret | IPV6_SOLICITED_NODE_MCAST);
+        }
+
+        return(IPV6_ADDRESS_MULTICAST);
+    }
+
+    tmp = ip_address[0] & (0xFFC00000);
+
+    if (tmp == (ULONG)0xFE800000)
+    {
+        return((ULONG)(IPV6_ADDRESS_UNICAST | IPV6_ADDRESS_LINKLOCAL));
+    }
+    /* Note that site local are deprecated in RFC 4291 and are
+       treated as global type address. */
+    if (tmp == (ULONG)0xFEC00000)
+    {
+        return((ULONG)(IPV6_ADDRESS_UNICAST | IPV6_ADDRESS_GLOBAL));
+    }
+
+    tmp = ip_address[0] | ip_address[1] | ip_address[2];
+
+    if (tmp == 0)
+    {
+        if (ip_address[3] == 0)
+        {
+            return(IPV6_ADDRESS_UNSPECIFIED);
+        }
+
+        if (ip_address[3] == 1)
+        {
+            return(IPV6_ADDRESS_LOOPBACK);
+        }
+    }
+
+    return((ULONG)(IPV6_ADDRESS_UNICAST | IPV6_ADDRESS_GLOBAL));
+#else /* FEATURE_NX_IPV6 */
+    NX_PARAMETER_NOT_USED(ip_address);
+
+    return(0);
+#endif /* FEATURE_NX_IPV6 */
+}
+
+#ifdef NX_LITTLE_ENDIAN
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_ipv6_address_change_endian                      PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function only applies to little endian hosts.  It performs     */
+/*    byte swaps on an IPv6 address.                                      */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    address                            The 128-bit IPv6 address to be   */
+/*                                          swapped.                      */
+/*                                                                        */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    NetX Source Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID _nx_ipv6_address_change_endian(ULONG *address)
+{
+#ifdef FEATURE_NX_IPV6
+    if (address == NX_NULL)
+    {
+        return;
+    }
+
+    NX_CHANGE_ULONG_ENDIAN(address[0]);
+    NX_CHANGE_ULONG_ENDIAN(address[1]);
+    NX_CHANGE_ULONG_ENDIAN(address[2]);
+    NX_CHANGE_ULONG_ENDIAN(address[3]);
+#else
+    NX_PARAMETER_NOT_USED(address);
+#endif /* FEATURE_NX_IPV6 */
+}
+
+#endif /* NX_LITTLE_ENDIAN */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_nd_cache_add_entry.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_nd_cache_add_entry.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_nd_cache_add_entry.c	(revision 69)
@@ -0,0 +1,225 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Neighbor Discovery Cache                                            */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_nd_cache.h"
+
+#ifdef FEATURE_NX_IPV6
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_nd_cache_add_entry                              PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This internal function finds an entry in the ND cache that is       */
+/*    mapped to the specified IPv6 address.  If the entry does not exist, */
+/*    this function allocates an empty entry and add the IP address to it.*/
+/*                                                                        */
+/*  Note:                                                                 */
+/*                                                                        */
+/*    This routine acquires the nx_nd_cache_protection mutex.             */
+/*       Application shall not hold this mutex before calling this        */
+/*       function.                                                        */
+/*                                                                        */
+/*    If the table is full and NetX Duo is configured to purge older      */
+/*    entries to make room for new entries, NetX Duo attempts to find the */
+/*    the best candidate to remove (STALE or REACHABLE).  NetX Duo        */
+/*    will not remove any cache entries in the INCOMPLETE, PROBE or DELAY */
+/*    state since these are probably being processed e.g. neighborhood    */
+/*    discovery by NetX Duo during this time.                             */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                   Pointer to IP instance                     */
+/*    dest_ip                  The IP address to match                    */
+/*    iface_address            Pointer to the IPv6 address structure      */
+/*    nd_cache_entry           User specified storage space for pointer to*/
+/*                               the corresponding ND cache.              */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS              ND cache entry found, contains valid value  */
+/*    NX_NOT_SUCCESSFUL       ND cache entry not found or entry is invalid*/
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    tx_mutex_get                          Obtain protection mutex       */
+/*    tx_mutex_put                          Release protection mutex      */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_icmpv6_process_redirect                                         */
+/*    _nx_ipv6_packet_send                                                */
+/*    _nx_nd_cache_add                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+
+UINT _nx_nd_cache_add_entry(NX_IP *ip_ptr, ULONG *dest_ip,
+                            NXD_IPV6_ADDRESS *iface_address,
+                            ND_CACHE_ENTRY **nd_cache_entry)
+{
+
+UINT i;
+UINT index;
+UINT first_available;
+#ifndef NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES
+UINT stale_timer_ticks;
+UINT timer_ticks_left;
+#endif
+
+    NX_PARAMETER_NOT_USED(ip_ptr);
+
+    /* Set the found slot past the end of the table. If a match or available
+       slot found, this will have a lower value. */
+    first_available = NX_IPV6_NEIGHBOR_CACHE_SIZE;
+
+    /* Initialize the return value. */
+    *nd_cache_entry = NX_NULL;
+
+    /* Compute a simple hash based on the destination IP address. */
+    index = (UINT)((dest_ip[0] + dest_ip[1] + dest_ip[2] + dest_ip[3]) %
+                   (NX_IPV6_NEIGHBOR_CACHE_SIZE));
+
+#ifndef NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES
+
+    /* Set the lowest possible timer ticks left to compare to. */
+    stale_timer_ticks = 0;
+
+    /* Start out at a very high number of remaining ticks to compare to. */
+    timer_ticks_left = 0xFFFFFFFF;
+#endif
+
+    /* Loop through all the entries. */
+    for (i = 0; i < NX_IPV6_NEIGHBOR_CACHE_SIZE; i++, index++)
+    {
+
+        /* Check for overflow */
+        if (index == NX_IPV6_NEIGHBOR_CACHE_SIZE)
+        {
+
+            /* Start back at the first table entry. */
+            index = 0;
+        }
+
+        /* Is the current entry available? */
+        if (ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_nd_status == ND_CACHE_STATE_INVALID)
+        {
+
+            /* There is a chance the entry to add does not exist in the table. We create one using the
+               invalid entry. */
+            first_available = index;
+            break;
+        }
+
+#ifndef NX_DISABLE_IPV6_PURGE_UNUSED_CACHE_ENTRIES
+        /* Skip over routers and static entries. */
+        if (ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_is_router != NX_NULL || ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_is_static)
+        {
+            continue;
+        }
+
+        /* Purging is enabled;
+           Attempt to find a STALE entry and if there is more than one,
+           choose the oldest one e.g. the highest timer ticks elapsed. */
+
+        /* Check for stale entries. These are the best candidates for 'recycling.' */
+        if (ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_nd_status == ND_CACHE_STATE_STALE)
+        {
+
+            /* Find the 'Stale' cache entry with the highest timer tick since
+               timer tick is incremented in the Stale state.*/
+            if (ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_timer_tick > stale_timer_ticks)
+            {
+                /* Set this entry as the oldest stale entry. */
+                stale_timer_ticks = (UINT)ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_timer_tick;
+                first_available = index;
+            }
+        }
+        /* Next try finding a REACHABLE entry closest to its cache table expiration date. */
+        else if (stale_timer_ticks == 0 &&
+                 ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_nd_status == ND_CACHE_STATE_REACHABLE)
+        {
+
+            /* Is this entry older that our previous oldest entry? */
+            if (ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_timer_tick < timer_ticks_left)
+            {
+
+                /* Set this entry as the oldest entry using timer ticks left. */
+                timer_ticks_left = (UINT)ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_timer_tick;
+                first_available = index;
+            }
+        }
+#endif
+    }
+
+    /* Did not find a available entry. */
+    if (first_available == NX_IPV6_NEIGHBOR_CACHE_SIZE)
+    {
+
+        /* Return unsuccessful status. */
+        return(NX_NOT_SUCCESSFUL);
+    }
+
+    /* Yes; before we invalidate and delete the entry, we need to
+       clean the nd cache. */
+    _nx_nd_cache_delete_internal(ip_ptr, &ip_ptr -> nx_ipv6_nd_cache[first_available]);
+
+    /* Record the IP address. */
+    COPY_IPV6_ADDRESS(dest_ip, ip_ptr -> nx_ipv6_nd_cache[first_available].nx_nd_cache_dest_ip);
+
+    /* A new entry starts with CREATED status. */
+    ip_ptr -> nx_ipv6_nd_cache[first_available].nx_nd_cache_nd_status = ND_CACHE_STATE_CREATED;
+
+    ip_ptr -> nx_ipv6_nd_cache[first_available].nx_nd_cache_outgoing_address = iface_address;
+
+    ip_ptr -> nx_ipv6_nd_cache[first_available].nx_nd_cache_interface_ptr = iface_address -> nxd_ipv6_address_attached;
+
+    /* Release the protection. */
+    *nd_cache_entry = &ip_ptr -> nx_ipv6_nd_cache[first_available];
+
+    return(NX_SUCCESS);
+}
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_nd_cache_delete_internal.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_nd_cache_delete_internal.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_nd_cache_delete_internal.c	(revision 69)
@@ -0,0 +1,167 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Neighbor Discovery Cache                                            */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_nd_cache.h"
+#include "nx_packet.h"
+#include "nx_icmpv6.h"
+
+#ifdef FEATURE_NX_IPV6
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    nx_nd_cache_delete_internal                         PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function deletes an IPv6 and MAC mapping from the ND cache     */
+/*    table.                                                              */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP.                */
+/*    dest_ip                               Pointer to the IP address.    */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    NX_SUCCESS                            Address is deleted            */
+/*    NX_ENTRY_NOT_FOUND                    Address not found in cache    */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_packet_transmit_releas            Packet Release                */
+/*    memset                                                              */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    nxd_ipv6_disable                                                    */
+/*    nx_nd_cache_fast_periodic_update                                    */
+/*    nxd_nd_cache_entry_delete                                           */
+/*                                                                        */
+/*  Note:                                                                 */
+/*                                                                        */
+/*    This routine is an internal function.  Therefore it assumes the     */
+/*       mutex is already locked.  Caller is responsible for accquiring   */
+/*       and releasing the mutex before invoking this routine.            */
+/*                                                                        */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT _nx_nd_cache_delete_internal(NX_IP *ip_ptr, ND_CACHE_ENTRY *entry)
+{
+
+UINT       i = 0, table_size;
+NX_PACKET *pkt, *next_pkt;
+
+    /* Free up the queued packets. */
+    pkt = entry -> nx_nd_cache_packet_waiting_head;
+
+    /* Flush any packets enqueued waiting on neighbor reachability confirmation. */
+    while (pkt)
+    {
+
+        next_pkt = pkt -> nx_packet_queue_next;
+        _nx_packet_transmit_release(pkt);
+        pkt = next_pkt;
+    }
+    entry -> nx_nd_cache_packet_waiting_queue_length = 0;
+
+    /* Clear the pointers to the original start and end of the packet queue. */
+    entry -> nx_nd_cache_packet_waiting_head = NX_NULL;
+    entry -> nx_nd_cache_packet_waiting_tail = NX_NULL;
+
+    /* Initialize the rest of the fields. */
+    memset(entry -> nx_nd_cache_mac_addr, 0, 6);
+
+    /* Clear the entry out.  */
+    entry -> nx_nd_cache_nd_status = ND_CACHE_STATE_INVALID;
+    entry -> nx_nd_cache_is_static = 0;
+
+    /* Is there a corresponding link in the default router list? */
+    if (entry -> nx_nd_cache_is_router)
+    {
+
+        /* Set its pointer to this entry in the cache table to NULL. */
+        entry -> nx_nd_cache_is_router -> nx_ipv6_default_router_entry_neighbor_cache_ptr = NX_NULL;
+    }
+
+    /* And indicate that this cache entry is no longer a router. */
+    entry -> nx_nd_cache_is_router = NX_NULL;
+
+    /* Set a local variable for convenience. */
+    table_size = ip_ptr -> nx_ipv6_destination_table_size;
+
+    while (table_size && i < NX_IPV6_DESTINATION_TABLE_SIZE)
+    {
+
+        /* Skip invalid entries. */
+        if (!ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid)
+        {
+            i++;
+            continue;
+        }
+
+        /* Keep track of valid entries we have checked. */
+        table_size--;
+
+        /* Find the destination unit. */
+        if (ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_nd_entry == entry)
+        {
+
+            /* Set the status. */
+            ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid = 0;
+
+            /* Set its pointer to this entry in the destination table to NULL. */
+            ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_nd_entry = NX_NULL;
+
+            /* Update the destination_table size. */
+            ip_ptr -> nx_ipv6_destination_table_size--;
+        }
+
+        i++;
+    }
+
+    return(NX_SUCCESS);
+}
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_nd_cache_find_entry.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_nd_cache_find_entry.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_nd_cache_find_entry.c	(revision 69)
@@ -0,0 +1,122 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Neighbor Discovery Cache                                            */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_nd_cache.h"
+
+#ifdef FEATURE_NX_IPV6
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    nx_nd_cache_find_entry                              PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This internal function finds an entry in the ND cache that is       */
+/*    mapped to the specified IPv6 address.                               */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                   IP instance pointer                        */
+/*    dest_ip                  The IP address to match                    */
+/*    nd_cache_entry           User specified storage space of pointer to */
+/*                                the corresponding ND cache.             */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                   NX_SUCCESS: The ND cache entry is located. */
+/*                                nd_cache_entry contains valid value.    */
+/*                             NX_NOT_SUCCESSFUL:  The ND cache entry     */
+/*                                cannot be found, or nd_cache_entry is   */
+/*                                NULL.                                   */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT _nx_nd_cache_find_entry(NX_IP *ip_ptr,
+                             ULONG *dest_ip, ND_CACHE_ENTRY **nd_cache_entry)
+{
+UINT i;
+UINT index;
+
+    /* Initialize the return value. */
+    *nd_cache_entry = NX_NULL;
+
+    /* Compute a simple hash based on the dest_ip */
+    index = (UINT)((dest_ip[0] + dest_ip[1] + dest_ip[2] + dest_ip[3]) %
+                   (NX_IPV6_NEIGHBOR_CACHE_SIZE));
+
+    for (i = 0; i < NX_IPV6_NEIGHBOR_CACHE_SIZE; i++)
+    {
+
+        if ((ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_nd_status != ND_CACHE_STATE_INVALID) &&
+            (ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_interface_ptr) &&
+            (CHECK_IPV6_ADDRESSES_SAME(&ip_ptr -> nx_ipv6_nd_cache[index].nx_nd_cache_dest_ip[0], dest_ip)))
+        {
+
+            /* find the entry */
+            *nd_cache_entry = &ip_ptr -> nx_ipv6_nd_cache[index];
+
+            return(NX_SUCCESS);
+        }
+
+        index++;
+
+        /* Check for overflow */
+        if (index == NX_IPV6_NEIGHBOR_CACHE_SIZE)
+        {
+            index = 0;
+        }
+    }
+
+    return(NX_NOT_SUCCESSFUL);
+}
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_allocate.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_allocate.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_allocate.c	(revision 69)
@@ -0,0 +1,293 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Packet Pool Management (Packet)                                     */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "tx_thread.h"
+#include "nx_packet.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_packet_allocate                                 PORTABLE C      */
+/*                                                           6.4.0        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function allocates a packet from the specified packet pool.    */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    pool_ptr                              Pool to allocate packet from  */
+/*    packet_ptr                            Pointer to place allocated    */
+/*                                            packet pointer              */
+/*    packet_type                           Type of packet to allocate    */
+/*    wait_option                           Suspension option             */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Completion status             */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _tx_thread_system_suspend             Suspend thread                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*  12-31-2023     Yajun Xia                Modified comment(s),          */
+/*                                            supported VLAN and generic  */
+/*                                            link layer,                 */
+/*                                            resulting in version 6.4.0  */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nx_packet_allocate(NX_PACKET_POOL *pool_ptr,  NX_PACKET **packet_ptr,
+                          ULONG packet_type, ULONG wait_option)
+{
+TX_INTERRUPT_SAVE_AREA
+
+UINT       status;              /* Return status           */
+TX_THREAD *thread_ptr;          /* Working thread pointer  */
+NX_PACKET *work_ptr;            /* Working packet pointer  */
+
+#ifdef TX_ENABLE_EVENT_TRACE
+TX_TRACE_BUFFER_ENTRY *trace_event;
+ULONG                  trace_timestamp;
+#endif
+
+    /* Make sure the packet_type does not go beyond nx_packet_data_end. */
+    if (pool_ptr -> nx_packet_pool_payload_size < packet_type)
+    {
+        return(NX_INVALID_PARAMETERS);
+    }
+
+    /* Set the return pointer to NULL initially.  */
+    *packet_ptr =   NX_NULL;
+
+    /* If trace is enabled, insert this event into the trace buffer.  */
+    NX_TRACE_IN_LINE_INSERT(NX_TRACE_PACKET_ALLOCATE, pool_ptr, 0, packet_type, pool_ptr -> nx_packet_pool_available, NX_TRACE_PACKET_EVENTS, &trace_event, &trace_timestamp);
+
+    /* Disable interrupts to get a packet from the pool.  */
+    TX_DISABLE
+
+    /* Determine if there is an available packet.  */
+    if (pool_ptr -> nx_packet_pool_available)
+    {
+
+        /* Yes, a packet is available.  Decrement the available count.  */
+        pool_ptr -> nx_packet_pool_available--;
+
+        /* Pickup the current packet pointer.  */
+        work_ptr =  pool_ptr -> nx_packet_pool_available_list;
+
+        /* Modify the available list to point at the next packet in the pool. */
+        pool_ptr -> nx_packet_pool_available_list =  work_ptr -> nx_packet_queue_next;
+
+        /* Setup various fields for this packet.  */
+        work_ptr -> nx_packet_queue_next =   NX_NULL;
+#ifndef NX_DISABLE_PACKET_CHAIN
+        work_ptr -> nx_packet_next =         NX_NULL;
+        work_ptr -> nx_packet_last =         NX_NULL;
+#endif /* NX_DISABLE_PACKET_CHAIN */
+        work_ptr -> nx_packet_length =       0;
+        work_ptr -> nx_packet_prepend_ptr =  work_ptr -> nx_packet_data_start + packet_type;
+        work_ptr -> nx_packet_append_ptr =   work_ptr -> nx_packet_prepend_ptr;
+        work_ptr -> nx_packet_address.nx_packet_interface_ptr = NX_NULL;
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+        work_ptr -> nx_packet_interface_capability_flag = 0;
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+        /* Set the TCP queue to the value that indicates it has been allocated.  */
+        /*lint -e{923} suppress cast of ULONG to pointer.  */
+        work_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next =  (NX_PACKET *)NX_PACKET_ALLOCATED;
+
+#ifdef FEATURE_NX_IPV6
+
+        /* Clear the option state. */
+        work_ptr -> nx_packet_option_state = 0;
+#endif /* FEATURE_NX_IPV6 */
+
+#ifdef NX_IPSEC_ENABLE
+
+        /* Clear the ipsec state. */
+        work_ptr -> nx_packet_ipsec_state = 0;
+        work_ptr -> nx_packet_ipsec_sa_ptr = NX_NULL;
+#endif /* NX_IPSEC_ENABLE */
+
+#ifndef NX_DISABLE_IPV4
+        /* Initialize the IP version field */
+        work_ptr -> nx_packet_ip_version = NX_IP_VERSION_V4;
+#endif /* !NX_DISABLE_IPV4  */
+
+        /* Initialize the IP identification flag.  */
+        work_ptr -> nx_packet_identical_copy = NX_FALSE;
+
+#ifdef NX_ENABLE_VLAN
+        /* Initialize the packet vlan priority */
+        work_ptr -> nx_packet_vlan_priority = NX_VLAN_PRIORITY_INVALID;
+#endif /* NX_ENABLE_VLAN */
+
+        /* Initialize the IP header length. */
+        work_ptr -> nx_packet_ip_header_length = 0;
+
+#ifdef NX_ENABLE_THREAD
+        work_ptr -> nx_packet_type = 0;
+#endif /* NX_ENABLE_THREAD  */
+
+        /* Place the new packet pointer in the return destination.  */
+        *packet_ptr =  work_ptr;
+
+        /* Set status to success.  */
+        status =  NX_SUCCESS;
+
+        /* Add debug information. */
+        NX_PACKET_DEBUG(__FILE__, __LINE__, work_ptr);
+    }
+    else
+    {
+
+#ifndef NX_DISABLE_PACKET_INFO
+        /* Increment the packet pool empty request count.  */
+        pool_ptr -> nx_packet_pool_empty_requests++;
+#endif
+
+        /* Determine if the request specifies suspension.  */
+        if (wait_option)
+        {
+
+            /* Prepare for suspension of this thread.  */
+
+#ifndef NX_DISABLE_PACKET_INFO
+            /* Increment the packet pool empty request suspension count.  */
+            pool_ptr -> nx_packet_pool_empty_suspensions++;
+#endif
+
+            /* Pickup thread pointer.  */
+            thread_ptr =  _tx_thread_current_ptr;
+
+            /* Setup cleanup routine pointer.  */
+            thread_ptr -> tx_thread_suspend_cleanup =  _nx_packet_pool_cleanup;
+
+            /* Setup cleanup information, i.e. this pool control
+               block.  */
+            thread_ptr -> tx_thread_suspend_control_block =  (void *)pool_ptr;
+
+            /* Save the return packet pointer address as well.  */
+            thread_ptr -> tx_thread_additional_suspend_info =  (void *)packet_ptr;
+
+            /* Save the packet type (or prepend offset) so this can be added
+               after a new packet becomes available.  */
+            thread_ptr -> tx_thread_suspend_info =  packet_type;
+
+            /* Setup suspension list.  */
+            if (pool_ptr -> nx_packet_pool_suspension_list)
+            {
+
+                /* This list is not NULL, add current thread to the end. */
+                thread_ptr -> tx_thread_suspended_next =
+                    pool_ptr -> nx_packet_pool_suspension_list;
+                thread_ptr -> tx_thread_suspended_previous =
+                    (pool_ptr -> nx_packet_pool_suspension_list) -> tx_thread_suspended_previous;
+                ((pool_ptr -> nx_packet_pool_suspension_list) -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
+                    thread_ptr;
+                (pool_ptr -> nx_packet_pool_suspension_list) -> tx_thread_suspended_previous =   thread_ptr;
+            }
+            else
+            {
+
+                /* No other threads are suspended.  Setup the head pointer and
+                   just setup this threads pointers to itself.  */
+                pool_ptr -> nx_packet_pool_suspension_list =  thread_ptr;
+                thread_ptr -> tx_thread_suspended_next =            thread_ptr;
+                thread_ptr -> tx_thread_suspended_previous =        thread_ptr;
+            }
+
+            /* Increment the suspended thread count.  */
+            pool_ptr -> nx_packet_pool_suspended_count++;
+
+            /* Set the state to suspended.  */
+            thread_ptr -> tx_thread_state =  TX_TCP_IP;
+
+            /* Set the suspending flag.  */
+            thread_ptr -> tx_thread_suspending =  TX_TRUE;
+
+            /* Temporarily disable preemption.  */
+            _tx_thread_preempt_disable++;
+
+            /* Save the timeout value.  */
+            thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks =  wait_option;
+
+            /* Restore interrupts.  */
+            TX_RESTORE
+
+            /* Call actual thread suspension routine.  */
+            _tx_thread_system_suspend(thread_ptr);
+
+            /* Update the trace event with the status.  */
+            NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_PACKET_ALLOCATE, 0, *packet_ptr, 0, 0);
+
+#ifdef NX_ENABLE_PACKET_DEBUG_INFO
+            if (thread_ptr -> tx_thread_suspend_status == NX_SUCCESS)
+            {
+
+                /* Add debug information. */
+                NX_PACKET_DEBUG(__FILE__, __LINE__, *packet_ptr);
+            }
+#endif /* NX_ENABLE_PACKET_DEBUG_INFO */
+
+            /* Return the completion status.  */
+            return(thread_ptr -> tx_thread_suspend_status);
+        }
+        else
+        {
+
+            /* Immediate return, return error completion.  */
+            status =  NX_NO_PACKET;
+        }
+    }
+
+    /* Restore interrupts.  */
+    TX_RESTORE
+
+    /* Update the trace event with the status.  */
+    NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_PACKET_ALLOCATE, 0, *packet_ptr, 0, 0);
+
+    /* Return completion status.  */
+    return(status);
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_copy.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_copy.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_copy.c	(revision 69)
@@ -0,0 +1,240 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Packet Pool Management (Packet)                                     */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_packet.h"
+#include "nx_ipv6.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_packet_copy                                     PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function copies the specified packet into one or more packets  */
+/*    allocated from the specified packet pool.                           */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    packet_ptr                            Pointer to source packet      */
+/*    new_packet_ptr                        Pointer for return packet     */
+/*    pool_ptr                              Pointer to packet pool to use */
+/*                                            for new packet(s)           */
+/*    wait_option                           Timeout option on packet      */
+/*                                            allocate and data append    */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Actual completion status      */
+/*    NX_SUCCESS                            Successful completion status  */
+/*    NX_INVALID_PACKET                     If zero packet payload or data*/
+/*                                            to copy                     */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_packet_allocate                   Allocate data packet          */
+/*    _nx_packet_data_append                Packet data append service    */
+/*    _nx_packet_release                    Release data packet           */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nx_packet_copy(NX_PACKET *packet_ptr, NX_PACKET **new_packet_ptr,
+                      NX_PACKET_POOL *pool_ptr, ULONG wait_option)
+{
+
+NX_PACKET *work_ptr;                    /* Working packet pointer     */
+NX_PACKET *source_ptr;                  /* Source packet pointer      */
+ULONG      size;                        /* Packet data size           */
+UINT       status;                      /* Return status              */
+UINT       first_packet;                /* First packet flag          */
+UINT       data_prepend_offset;         /* Data prepend offset        */
+UINT       ip_header_offset;            /* IP header offset           */
+
+#ifdef TX_ENABLE_EVENT_TRACE
+TX_TRACE_BUFFER_ENTRY *trace_event;
+ULONG                  trace_timestamp;
+#endif
+
+
+    /* Default the return packet pointer to NULL.  */
+    *new_packet_ptr =  NX_NULL;
+
+    /* Default the first packet to TRUE.  */
+    first_packet = NX_TRUE;
+
+    /* If trace is enabled, insert this event into the trace buffer.  */
+    NX_TRACE_IN_LINE_INSERT(NX_TRACE_PACKET_COPY, packet_ptr, 0, pool_ptr, wait_option, NX_TRACE_PACKET_EVENTS, &trace_event, &trace_timestamp);
+
+    /* Determine if there is anything to copy.  */
+    if (packet_ptr -> nx_packet_length == 0)
+    {
+
+        /* Empty source packet, return an error.  */
+        return(NX_INVALID_PACKET);
+    }
+
+    /* Allocate a new packet from the default packet pool supplied.  */
+    /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+    status =  _nx_packet_allocate(pool_ptr, &work_ptr, 0, wait_option);
+
+    /* Determine if the packet was not allocated.  */
+    if (status != NX_SUCCESS)
+    {
+
+        /* Return the error code from the packet allocate routine.  */
+        return(status);
+    }
+
+    /* Copy the packet interface information. */
+    /*lint -e{644} suppress variable might not be initialized, since "work_ptr" was initialized by _nx_packet_allocate. */
+    work_ptr -> nx_packet_address.nx_packet_interface_ptr = packet_ptr -> nx_packet_address.nx_packet_interface_ptr;
+
+#ifdef FEATURE_NX_IPV6
+
+    /* Copy the IP version information. */
+    work_ptr -> nx_packet_ip_version = packet_ptr -> nx_packet_ip_version;
+#endif /* FEATURE_NX_IPV6 */
+
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+
+    /* Copy the packet interface capability. */
+    work_ptr -> nx_packet_interface_capability_flag = packet_ptr -> nx_packet_interface_capability_flag;
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+
+#ifdef NX_IPSEC_ENABLE
+    work_ptr -> nx_packet_ipsec_sa_ptr = packet_ptr -> nx_packet_ipsec_sa_ptr;
+#endif /* NX_IPSEC_ENABLE */
+
+    /* Save the source packet pointer.  */
+    source_ptr =  packet_ptr;
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+    /* Loop to copy the original packet's data.  */
+    do
+    {
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+        /* Check if it is the first packet.  */
+        if (first_packet == NX_TRUE)
+        {
+
+            /* Yes, it is, copied the data beginning at data starting position.  */
+
+            /* Calculate this packet's data size.  */
+            /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+            size =  (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_data_start);
+
+            /* Copy the data from the source packet into the new packet using
+               the data append feature.  */
+            status =  _nx_packet_data_append(work_ptr, packet_ptr -> nx_packet_data_start, size, pool_ptr, wait_option);
+        }
+        else
+        {
+
+            /* Calculate this packet's data size.  */
+            /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+            size =  (ULONG)(packet_ptr -> nx_packet_append_ptr - packet_ptr -> nx_packet_prepend_ptr);
+
+            /* Copy the data from the source packet into the new packet using
+               the data append feature.  */
+            status =  _nx_packet_data_append(work_ptr, packet_ptr -> nx_packet_prepend_ptr, size, pool_ptr, wait_option);
+        }
+
+        /* Determine if there was an error in the data append.  */
+        if (status != NX_SUCCESS)
+        {
+
+            /* An error is present, release the new packet.  */
+            _nx_packet_release(work_ptr);
+
+            /* Return the error code from the packet data append service.  */
+            return(status);
+        }
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+        /* Move to the next packet in the packet chain.  */
+        packet_ptr =  packet_ptr -> nx_packet_next;
+
+        /* Set the first packet to FALSE.  */
+        first_packet = NX_FALSE;
+    } while (packet_ptr);
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+    /* Adjust the prepend pointer and data length.  */
+    /*lint --e{946} --e{947} --e{732} suppress pointer subtraction, since it is necessary. */
+    data_prepend_offset = (UINT)(source_ptr -> nx_packet_prepend_ptr - source_ptr -> nx_packet_data_start);
+    work_ptr -> nx_packet_prepend_ptr = work_ptr -> nx_packet_data_start + data_prepend_offset;
+    work_ptr -> nx_packet_length =  work_ptr -> nx_packet_length - data_prepend_offset;
+
+    /* Set the ip_header information. */
+    ip_header_offset = (UINT)(source_ptr -> nx_packet_ip_header - source_ptr -> nx_packet_data_start);
+    work_ptr -> nx_packet_ip_header = work_ptr -> nx_packet_data_start + ip_header_offset;
+
+    /* Determine if the packet copy was successful.  */
+    if (source_ptr -> nx_packet_length != work_ptr -> nx_packet_length)
+    {
+
+        /* An error is present, release the new packet.  */
+        _nx_packet_release(work_ptr);
+
+        /* Return an error code.  */
+        return(NX_INVALID_PACKET);
+    }
+    else
+    {
+
+        /* Everything is okay, return the new packet pointer.  */
+        *new_packet_ptr =  work_ptr;
+
+        /* Add debug information. */
+        NX_PACKET_DEBUG(__FILE__, __LINE__, work_ptr);
+
+        /* Update the trace event with the status.  */
+        NX_TRACE_EVENT_UPDATE(trace_event, trace_timestamp, NX_TRACE_PACKET_COPY, 0, work_ptr, 0, 0);
+
+        /* Return success status.  */
+        return(NX_SUCCESS);
+    }
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_data_append.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_data_append.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_data_append.c	(revision 69)
@@ -0,0 +1,296 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Packet Pool Management (Packet)                                     */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_packet.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_packet_data_append                              PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function copies the specified data to the end of the specified */
+/*    packet.  Additional packets are allocated from the specified pool   */
+/*    if needed.                                                          */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    packet_ptr                            Pointer to packet to append to*/
+/*    data_start                            Pointer to start of the data  */
+/*    data_size                             Number of bytes to append     */
+/*    pool_ptr                              Pool to allocate packet from  */
+/*    wait_option                           Suspension option             */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Completion status             */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_packet_allocate                   Allocate data packet          */
+/*    _nx_packet_release                    Release data packet           */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s), and      */
+/*                                            verified memcpy use cases,  */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nx_packet_data_append(NX_PACKET *packet_ptr, VOID *data_start, ULONG data_size,
+                             NX_PACKET_POOL *pool_ptr, ULONG wait_option)
+{
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+UINT       status;                 /* Return status              */
+NX_PACKET *new_list_ptr;           /* Head of new list pointer   */
+NX_PACKET *last_packet =  NX_NULL; /* Last supplied packet       */
+#endif /* NX_DISABLE_PACKET_CHAIN */
+ULONG      available_bytes;        /* Number of available bytes  */
+ULONG      copy_size;              /* Size for each memory copy  */
+UCHAR     *source_ptr;             /* Buffer source pointer      */
+NX_PACKET *work_ptr;               /* Working packet pointer     */
+
+
+    /* If trace is enabled, insert this event into the trace buffer.  */
+    NX_TRACE_IN_LINE_INSERT(NX_TRACE_PACKET_DATA_APPEND, packet_ptr, data_start, data_size, pool_ptr, NX_TRACE_PACKET_EVENTS, 0, 0);
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+    /* Calculate the number of bytes available at the end of the supplied packet.  */
+    if (packet_ptr -> nx_packet_last)
+    {
+
+        /* More than one packet.  Walk the packet chain starting at the last packet
+           to calculate the remaining bytes.  */
+        available_bytes =  0;
+        work_ptr =  packet_ptr -> nx_packet_last;
+        do
+        {
+
+            /* Calculate the available bytes in this packet.  */
+            /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+            /*lint -e{737} suppress loss of sign, since nx_packet_data_end is assumed to be larger than nx_packet_append_ptr. */
+            available_bytes =  available_bytes +
+                (ULONG)(work_ptr -> nx_packet_data_end - work_ptr -> nx_packet_append_ptr);
+
+            /* Remember the last packet.  */
+            last_packet =  work_ptr;
+
+            /* Move to the next packet.   There typically won't be another packet, but just in
+               case the logic is here for it!  */
+            work_ptr =  work_ptr -> nx_packet_next;
+        } while (work_ptr);
+    }
+    else
+#endif /* NX_DISABLE_PACKET_CHAIN */
+    {
+
+        /* Just calculate the number of bytes available in the first packet.  */
+        /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+        available_bytes =  (ULONG)(packet_ptr -> nx_packet_data_end - packet_ptr -> nx_packet_append_ptr);
+    }
+
+    /* Determine if any new packets are required to satisfy this request. */
+    if (available_bytes < data_size)
+    {
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+        /* Setup a temporary head pointer.  */
+        new_list_ptr =  NX_NULL;
+
+        /* Loop to pickup enough packets to complete the append request.  */
+        while (available_bytes < data_size)
+        {
+
+            /* Allocate a new packet.  */
+            status =  _nx_packet_allocate(pool_ptr, &work_ptr, 0, wait_option);
+
+            /* Determine if an error is present.  */
+            if (status)
+            {
+
+                /* Yes, an error is present.   */
+
+                /* First release any packets that have been allocated so far.  */
+                if (new_list_ptr)
+                {
+                    _nx_packet_release(new_list_ptr);
+                }
+
+                /* Return the error status to the caller of this service.  */
+                return(status);
+            }
+
+            /* Add debug information. */
+            NX_PACKET_DEBUG(__FILE__, __LINE__, work_ptr);
+
+            /* No error is present.  Link the new packet to the temporary list being built.  */
+            if (new_list_ptr)
+            {
+
+                /* Determine if there is already more than one packet on the list.  */
+                if (new_list_ptr -> nx_packet_last)
+                {
+
+                    /* Yes, link up the last packet to the new packet and update the
+                       last pointer.  */
+                    /*lint -e{644} suppress variable might not be initialized, since "work_ptr" was initialized in _nx_packet_allocate. */
+                    (new_list_ptr -> nx_packet_last) -> nx_packet_next =  work_ptr;
+                    new_list_ptr -> nx_packet_last =  work_ptr;
+                }
+                else
+                {
+
+                    /* Second packet allocated.  Just setup the last and next in the
+                       head pointer.  */
+                    new_list_ptr -> nx_packet_last =  work_ptr;
+                    new_list_ptr -> nx_packet_next =  work_ptr;
+                }
+            }
+            else
+            {
+
+                /* Just setup the temporary list head.  */
+                new_list_ptr =  work_ptr;
+            }
+
+            /* Adjust the number of available bytes according to how much space
+               is in the new packet.  */
+            /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+            /*lint -e{737} suppress loss of sign, since nx_packet_data_end is assumed to be larger than nx_packet_append_ptr. */
+            /*lint -e{613} suppress possible use of null pointer, since "work_ptr" was set in _nx_packet_allocate. */
+            available_bytes =  available_bytes +
+                (ULONG)(work_ptr -> nx_packet_data_end - work_ptr -> nx_packet_append_ptr);
+        }
+
+        /* At this point, all the necessary packets have been allocated and are present
+           on the temporary list.  We need to link this new list to the end of the supplied
+           packet.  */
+        if (last_packet)
+        {
+
+            /* Already more than one packet.  Add the new packet list to the end.  */
+            last_packet -> nx_packet_next =  new_list_ptr;
+        }
+        else
+        {
+
+            /* Link the new packet list to the head packet.  */
+            packet_ptr -> nx_packet_next =  new_list_ptr;
+        }
+
+        /* Clear the last packet that was used to maintain the new list.  */
+        /*lint -e{613} suppress possible use of null pointer, since "new_list_ptr" was set in previous loop. */
+        new_list_ptr -> nx_packet_last =  NX_NULL;
+#else
+        NX_PARAMETER_NOT_USED(pool_ptr);
+        NX_PARAMETER_NOT_USED(wait_option);
+
+        return(NX_SIZE_ERROR);
+#endif /* NX_DISABLE_PACKET_CHAIN */
+    }
+
+    /* Setup the new data length in the packet.  */
+    packet_ptr -> nx_packet_length =   packet_ptr -> nx_packet_length + data_size;
+
+    /* Now copy the supplied data buffer at the end of the packet.  */
+    source_ptr =  (UCHAR *)data_start;
+#ifndef NX_DISABLE_PACKET_CHAIN
+    if (packet_ptr -> nx_packet_last)
+    {
+        work_ptr =    packet_ptr -> nx_packet_last;
+    }
+    else
+    {
+#endif /* NX_DISABLE_PACKET_CHAIN */
+        work_ptr =    packet_ptr;
+#ifndef NX_DISABLE_PACKET_CHAIN
+    }
+    while (data_size)
+    {
+
+        /* Determine the amount of memory to copy.  */
+        /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+        if (data_size < (ULONG)(work_ptr -> nx_packet_data_end - work_ptr -> nx_packet_append_ptr))
+        {
+            copy_size =  data_size;
+        }
+        else
+        {
+
+            /*lint -e{946} -e{947} suppress pointer subtraction, since it is necessary. */
+            copy_size =  (ULONG)(work_ptr -> nx_packet_data_end - work_ptr -> nx_packet_append_ptr);
+        }
+#else
+        copy_size = data_size;
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+        /* Copy the data into the current packet buffer.  */
+        memcpy(work_ptr -> nx_packet_append_ptr, source_ptr, copy_size); /* Use case of memcpy is verified.  lgtm[cpp/banned-api-usage-required-any] */
+
+        /* Adjust the remaining data size.  */
+        data_size =  data_size - copy_size;
+
+        /* Update this packets append pointer.  */
+        work_ptr -> nx_packet_append_ptr =  work_ptr -> nx_packet_append_ptr + copy_size;
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+        /* Any more data left to append?  */
+        if (data_size)
+        {
+
+            /* Yes, there is more to move.  Update the source pointer, move the work pointer
+               to the next packet in the chain and update the last packet pointer.  */
+            source_ptr =  source_ptr + copy_size;
+            work_ptr =  work_ptr -> nx_packet_next;
+            packet_ptr -> nx_packet_last =  work_ptr;
+        }
+    }
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+    /* Return successful status.  */
+    return(NX_SUCCESS);
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_pool_cleanup.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_pool_cleanup.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_pool_cleanup.c	(revision 69)
@@ -0,0 +1,163 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Packet Pool Management (Packet)                                     */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "tx_thread.h"
+#include "nx_packet.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_packet_pool_cleanup                             PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function processes packet allocate timeout and thread terminate*/
+/*    actions that require the packet pool data structures to be cleaned  */
+/*    up.                                                                 */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    thread_ptr                            Pointer to suspended thread's */
+/*                                            control block               */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _tx_thread_system_resume              Resume thread service         */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _tx_thread_timeout                    Thread timeout processing     */
+/*    _tx_thread_terminate                  Thread terminate processing   */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID  _nx_packet_pool_cleanup(TX_THREAD *thread_ptr NX_CLEANUP_PARAMETER)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+NX_PACKET_POOL *pool_ptr;   /* Working packet pool pointer  */
+
+    NX_CLEANUP_EXTENSION
+
+    /* Setup pointer to packet pool control block.  */
+    pool_ptr =  (NX_PACKET_POOL *)thread_ptr -> tx_thread_suspend_control_block;
+
+    /* Disable interrupts to remove the suspended thread from the packet pool.  */
+    TX_DISABLE
+
+    /* Determine if the cleanup is still required.  */
+    if ((thread_ptr -> tx_thread_suspend_cleanup) && (pool_ptr) &&
+        (pool_ptr -> nx_packet_pool_id == NX_PACKET_POOL_ID))
+    {
+
+        /* Yes, we still have thread suspension!  */
+
+        /* Clear the suspension cleanup flag.  */
+        thread_ptr -> tx_thread_suspend_cleanup =  TX_NULL;
+
+        /* Remove the suspended thread from the list.  */
+
+        /* See if this is the only suspended thread on the list.  */
+        if (thread_ptr == thread_ptr -> tx_thread_suspended_next)
+        {
+
+            /* Yes, the only suspended thread.  */
+
+            /* Update the head pointer.  */
+            pool_ptr -> nx_packet_pool_suspension_list =  TX_NULL;
+        }
+        else
+        {
+
+            /* At least one more thread is on the same suspension list.  */
+
+            /* Update the list head pointer if necessary.  */
+            if (pool_ptr -> nx_packet_pool_suspension_list == thread_ptr)
+            {
+                pool_ptr -> nx_packet_pool_suspension_list =  thread_ptr -> tx_thread_suspended_next;
+            }
+
+            /* Update the links of the adjacent threads.  */
+            (thread_ptr -> tx_thread_suspended_next) -> tx_thread_suspended_previous =
+                thread_ptr -> tx_thread_suspended_previous;
+            (thread_ptr -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
+                thread_ptr -> tx_thread_suspended_next;
+        }
+
+        /* Decrement the suspension count.  */
+        pool_ptr -> nx_packet_pool_suspended_count--;
+
+        /* Now we need to determine if this cleanup is from a terminate, timeout,
+           or from a wait abort.  */
+        if (thread_ptr -> tx_thread_state == TX_TCP_IP)
+        {
+
+            /* Thread still suspended on the packet pool.  Setup return error status and
+               resume the thread.  */
+
+            /* Setup return status.  */
+            thread_ptr -> tx_thread_suspend_status =  NX_NO_PACKET;
+
+            /* Temporarily disable preemption.  */
+            _tx_thread_preempt_disable++;
+
+            /* Restore interrupts.  */
+            TX_RESTORE
+
+            /* Resume the thread!  Check for preemption even though we are executing
+               from the system timer thread right now which normally executes at the
+               highest priority.  */
+            _tx_thread_system_resume(thread_ptr);
+
+            /* Finished, just return.  */
+            return;
+        }
+    }
+
+    /* Restore interrupts.  */
+    TX_RESTORE
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_pool_create.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_pool_create.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_pool_create.c	(revision 69)
@@ -0,0 +1,243 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Packet Pool Management (Packet)                                     */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_packet.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_packet_pool_create                              PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function creates a pool of fixed-size packets within the       */
+/*    specified memory area.                                              */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    pool_ptr                              Packet Pool control block     */
+/*    name_ptr                              Packet Pool string pointer    */
+/*    payload_size                          Size of packet payload        */
+/*    pool_start                            Starting address of pool      */
+/*    pool_size                             Number of bytes in pool       */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Return status                 */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nx_packet_pool_create(NX_PACKET_POOL *pool_ptr, CHAR *name_ptr, ULONG payload_size,
+                             VOID *pool_start, ULONG pool_size)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+NX_PACKET_POOL *tail_ptr;              /* Working packet pool pointer */
+ULONG           packets;               /* Number of packets in pool   */
+ULONG           original_payload_size; /* Original payload size       */
+ULONG           header_size;           /* Rounded header size         */
+CHAR           *packet_ptr;            /* Working packet pointer      */
+CHAR           *next_packet_ptr;       /* Next packet pointer         */
+CHAR           *end_of_pool;           /* End of pool area            */
+CHAR           *payload_address;       /* Address of the first payload*/
+VOID           *rounded_pool_start;    /* Rounded stating address     */
+
+
+    /* Save the original payload size.  */
+    original_payload_size =  payload_size;
+
+    /* Align the starting address to four bytes. */
+    /*lint -e{923} suppress cast between ULONG and pointer.  */
+    rounded_pool_start = (VOID *)((((ALIGN_TYPE)pool_start + NX_PACKET_ALIGNMENT  - 1) / NX_PACKET_ALIGNMENT) * NX_PACKET_ALIGNMENT);
+
+    /* Round the pool size down to something that is evenly divisible by alignment.  */
+    /*lint -e{923} suppress cast between ULONG and pointer.  */
+    pool_size = (ULONG)(((pool_size - ((ALIGN_TYPE)rounded_pool_start - (ALIGN_TYPE)pool_start)) / NX_PACKET_ALIGNMENT) * NX_PACKET_ALIGNMENT);
+
+    /* Set the pool starting address. */
+    pool_start = rounded_pool_start;
+
+    /* Calculate the address of payload. */
+    /*lint -e{923} suppress cast between ULONG and pointer.  */
+    payload_address = (CHAR *)((ALIGN_TYPE)rounded_pool_start + sizeof(NX_PACKET));
+
+    /* Align the address of payload. */
+    /*lint -e{923} suppress cast between ULONG and pointer.  */
+    payload_address = (CHAR *)((((ALIGN_TYPE)payload_address + NX_PACKET_ALIGNMENT  - 1) / NX_PACKET_ALIGNMENT) * NX_PACKET_ALIGNMENT);
+
+    /* Calculate the header size. */
+    /*lint -e{923} suppress cast between ULONG and pointer.  */
+    header_size = (ULONG)((ALIGN_TYPE)payload_address - (ALIGN_TYPE)rounded_pool_start);
+
+    /* Round the packet size up to something that helps guarantee proper alignment for header and payload.  */
+    payload_size = (ULONG)(((header_size + payload_size + NX_PACKET_ALIGNMENT  - 1) / NX_PACKET_ALIGNMENT) * NX_PACKET_ALIGNMENT - header_size);
+
+    /* Clear pool fields. */
+    memset(pool_ptr, 0, sizeof(NX_PACKET_POOL));
+
+    /* Setup the basic packet pool fields.  */
+    pool_ptr -> nx_packet_pool_name =             name_ptr;
+    pool_ptr -> nx_packet_pool_suspension_list =  TX_NULL;
+    pool_ptr -> nx_packet_pool_suspended_count =  0;
+    pool_ptr -> nx_packet_pool_start =            (CHAR *)pool_start;
+    pool_ptr -> nx_packet_pool_size =             pool_size;
+    pool_ptr -> nx_packet_pool_payload_size =     original_payload_size;
+
+    /* Calculate the end of the pool's memory area.  */
+    end_of_pool =  ((CHAR *)pool_start) + pool_size;
+
+    /* Walk through the pool area, setting up the available packet list.  */
+    packets =            0;
+    packet_ptr =         (CHAR *)rounded_pool_start;
+    next_packet_ptr =    packet_ptr + (payload_size + header_size);
+
+    /*lint -e{946} suppress pointer subtraction, since it is necessary. */
+    while (next_packet_ptr <= end_of_pool)
+    {
+
+        /* Yes, we have another packet.  Increment the packet count.  */
+        packets++;
+
+        /* Setup the link to the next packet.  */
+        /*lint -e{929} -e{740} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        ((NX_PACKET *)packet_ptr) -> nx_packet_queue_next =  (NX_PACKET *)next_packet_ptr;
+
+        /* Remember that this packet pool is the owner.  */
+        /*lint -e{929} -e{740} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        ((NX_PACKET *)packet_ptr) -> nx_packet_pool_owner =  pool_ptr;
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+        /* Clear the next packet pointer.  */
+        /*lint -e{929} -e{740} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        ((NX_PACKET *)packet_ptr) -> nx_packet_next =  (NX_PACKET *)NX_NULL;
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+        /* Mark the packet as free.  */
+        /*lint -e{929} -e{923} -e{740} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        ((NX_PACKET *)packet_ptr) -> nx_packet_union_next.nx_packet_tcp_queue_next =  (NX_PACKET *)NX_PACKET_FREE;
+
+        /* Setup the packet data pointers.  */
+        /*lint -e{929} -e{928} -e{740} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        ((NX_PACKET *)packet_ptr) -> nx_packet_data_start =  (UCHAR *)(packet_ptr + header_size);
+
+        /*lint -e{929} -e{928} -e{740} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+        ((NX_PACKET *)packet_ptr) -> nx_packet_data_end =    (UCHAR *)(packet_ptr + header_size + original_payload_size);
+
+        /* Add debug information. */
+        NX_PACKET_DEBUG(__FILE__, __LINE__, (NX_PACKET *)packet_ptr);
+
+        /* Advance to the next packet.  */
+        packet_ptr =   next_packet_ptr;
+
+        /* Update the next packet pointer.  */
+        next_packet_ptr =  packet_ptr + (payload_size + header_size);
+    }
+
+    /* Backup to the last packet in the pool.  */
+    packet_ptr =  packet_ptr - (payload_size + header_size);
+
+    /* Set the last packet's forward pointer to NULL.  */
+    /*lint -e{929} -e{740} -e{826} suppress cast of pointer to pointer, since it is necessary  */
+    ((NX_PACKET *)packet_ptr) -> nx_packet_queue_next =  NX_NULL;
+
+    /* Save the remaining information in the pool control packet.  */
+    pool_ptr -> nx_packet_pool_available =  packets;
+    pool_ptr -> nx_packet_pool_total =      packets;
+
+    /* Set the packet pool available list.  */
+    pool_ptr -> nx_packet_pool_available_list =  (NX_PACKET *)pool_start;
+
+    /* If trace is enabled, register this object.  */
+    NX_TRACE_OBJECT_REGISTER(NX_TRACE_OBJECT_TYPE_PACKET_POOL, pool_ptr, name_ptr, payload_size, packets);
+
+    /* If trace is enabled, insert this event into the trace buffer.  */
+    NX_TRACE_IN_LINE_INSERT(NX_TRACE_PACKET_POOL_CREATE, pool_ptr, payload_size, pool_start, pool_size, NX_TRACE_PACKET_EVENTS, 0, 0);
+
+    /* Disable interrupts to place the packet pool on the created list.  */
+    TX_DISABLE
+
+    /* Setup the packet pool ID to make it valid.  */
+    pool_ptr -> nx_packet_pool_id =  NX_PACKET_POOL_ID;
+
+    /* Place the packet pool on the list of created packet pools.  First,
+       check for an empty list.  */
+    if (_nx_packet_pool_created_ptr)
+    {
+
+        /* Pickup tail pointer.  */
+        tail_ptr =  _nx_packet_pool_created_ptr -> nx_packet_pool_created_previous;
+
+        /* Place the new packet pool in the list.  */
+        _nx_packet_pool_created_ptr -> nx_packet_pool_created_previous =  pool_ptr;
+        tail_ptr -> nx_packet_pool_created_next =  pool_ptr;
+
+        /* Setup this packet pool's created links.  */
+        pool_ptr -> nx_packet_pool_created_previous =  tail_ptr;
+        pool_ptr -> nx_packet_pool_created_next =      _nx_packet_pool_created_ptr;
+    }
+    else
+    {
+
+        /* The created packet pool list is empty.  Add packet pool to empty list.  */
+        _nx_packet_pool_created_ptr =                  pool_ptr;
+        pool_ptr -> nx_packet_pool_created_next =      pool_ptr;
+        pool_ptr -> nx_packet_pool_created_previous =  pool_ptr;
+    }
+
+    /* Increment the number of packet pools created.  */
+    _nx_packet_pool_created_count++;
+
+    /* Restore interrupts.  */
+    TX_RESTORE
+
+    /* Return NX_SUCCESS.  */
+    return(NX_SUCCESS);
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_pool_initialize.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_pool_initialize.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_pool_initialize.c	(revision 69)
@@ -0,0 +1,84 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Packet Pool Management (Packet)                                     */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Locate NetX global Packet Pool Component data in this file.  */
+
+#define NX_PACKET_POOL_INIT
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_packet.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_packet_pool_initialize                          PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function initializes the packet pool management component.     */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_system_initialize                 System initialization         */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID    _nx_packet_pool_initialize(VOID)
+{
+
+    /* Initialize the head pointer of the created packet pools list and the
+       number of packet pools created.  */
+    _nx_packet_pool_created_ptr =        NX_NULL;
+    _nx_packet_pool_created_count =      0;
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_release.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_release.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_release.c	(revision 69)
@@ -0,0 +1,256 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Packet Pool Management (Packet)                                     */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "tx_thread.h"
+#include "nx_packet.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_packet_release                                  PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function releases the packet chain back to the appropriate     */
+/*    packet pools.                                                       */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    packet_ptr                            Pointer of packet to release  */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Completion status             */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _tx_thread_system_resume              Resume suspended thread       */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nx_packet_release(NX_PACKET *packet_ptr)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+NX_PACKET_POOL *pool_ptr;       /* Pool pointer            */
+TX_THREAD      *thread_ptr;     /* Working thread pointer  */
+#ifndef NX_DISABLE_PACKET_CHAIN
+NX_PACKET      *next_packet;    /* Working block pointer   */
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+
+    /* If trace is enabled, insert this event into the trace buffer.  */
+    NX_TRACE_IN_LINE_INSERT(NX_TRACE_PACKET_RELEASE, packet_ptr, packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next, (packet_ptr -> nx_packet_pool_owner) -> nx_packet_pool_available, 0, NX_TRACE_PACKET_EVENTS, 0, 0);
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+    /* Loop to free all packets chained together, not assuming they are
+       from the same pool.  */
+    while (packet_ptr)
+    {
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+        /* Check to see if the packet is releasable.  */
+        /*lint -e{923} suppress cast of ULONG to pointer.  */
+        if (packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next != ((NX_PACKET *)NX_PACKET_ALLOCATED))
+        {
+
+#ifndef NX_DISABLE_PACKET_INFO
+            /* Pickup the pool pointer.  */
+            pool_ptr =  packet_ptr -> nx_packet_pool_owner;
+
+            /* Check for a good pool pointer...  error must be the packet!  */
+            if ((pool_ptr) && (pool_ptr -> nx_packet_pool_id == NX_PACKET_POOL_ID))
+            {
+
+                /* Increment the packet pool invalid release error count.  */
+                pool_ptr -> nx_packet_pool_invalid_releases++;
+            }
+#endif
+
+            /* Return an error indicating the packet could not be released.  */
+            return(NX_PTR_ERROR);
+        }
+        /* End of packet check.  */
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+        /* Pickup the next packet. */
+        next_packet =  packet_ptr -> nx_packet_next;
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+        /* Add debug information. */
+        NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+        /* Disable interrupts to put this packet back in the packet pool.  */
+        TX_DISABLE
+
+        /* Pickup the pool pointer.  */
+        pool_ptr =  packet_ptr -> nx_packet_pool_owner;
+
+        /* Determine if there are any threads suspended on the block pool.  */
+        thread_ptr =  pool_ptr -> nx_packet_pool_suspension_list;
+        if (thread_ptr)
+        {
+
+            /* Remove the suspended thread from the list.  */
+
+            /* See if this is the only suspended thread on the list.  */
+            if (thread_ptr == thread_ptr -> tx_thread_suspended_next)
+            {
+
+                /* Yes, the only suspended thread.  */
+
+                /* Update the head pointer.  */
+                pool_ptr -> nx_packet_pool_suspension_list =  NX_NULL;
+            }
+            else
+            {
+
+                /* At least one more thread is on the same expiration list.  */
+
+                /* Update the list head pointer.  */
+                pool_ptr -> nx_packet_pool_suspension_list =  thread_ptr -> tx_thread_suspended_next;
+
+                /* Update the links of the adjacent threads.  */
+                (thread_ptr -> tx_thread_suspended_next) -> tx_thread_suspended_previous =
+                    thread_ptr -> tx_thread_suspended_previous;
+                (thread_ptr -> tx_thread_suspended_previous) -> tx_thread_suspended_next =
+                    thread_ptr -> tx_thread_suspended_next;
+            }
+
+            /* Decrement the suspension count.  */
+            pool_ptr -> nx_packet_pool_suspended_count--;
+
+            /* Prepare for resumption of the first thread.  */
+
+            /* Clear cleanup routine to avoid timeout.  */
+            thread_ptr -> tx_thread_suspend_cleanup =  TX_NULL;
+
+            /* Temporarily disable preemption.  */
+            _tx_thread_preempt_disable++;
+
+            /* Restore interrupts.  */
+            TX_RESTORE
+
+            /* Adjust this packet to look just like a new packet.  */
+            packet_ptr -> nx_packet_queue_next  =  NX_NULL;
+#ifndef NX_DISABLE_PACKET_CHAIN
+            packet_ptr -> nx_packet_next        =  NX_NULL;
+            packet_ptr -> nx_packet_last        =  NX_NULL;
+#endif /* NX_DISABLE_PACKET_CHAIN */
+            packet_ptr -> nx_packet_length      =  0;
+            packet_ptr -> nx_packet_prepend_ptr =  packet_ptr -> nx_packet_data_start + (thread_ptr -> tx_thread_suspend_info);
+            packet_ptr -> nx_packet_append_ptr  =  packet_ptr -> nx_packet_prepend_ptr;
+            packet_ptr -> nx_packet_address.nx_packet_interface_ptr = NX_NULL;
+#ifdef NX_ENABLE_INTERFACE_CAPABILITY
+            packet_ptr -> nx_packet_interface_capability_flag = 0;
+#endif /* NX_ENABLE_INTERFACE_CAPABILITY */
+            /* Set the TCP queue to the value that indicates it has been allocated.  */
+            /*lint -e{923} suppress cast of ULONG to pointer.  */
+            packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next =  (NX_PACKET *)NX_PACKET_ALLOCATED;
+
+#ifdef FEATURE_NX_IPV6
+
+            /* Clear the option state. */
+            packet_ptr -> nx_packet_option_state = 0;
+#endif /* FEATURE_NX_IPV6 */
+
+#ifdef NX_IPSEC_ENABLE
+
+            /* Clear the ipsec state. */
+            packet_ptr -> nx_packet_ipsec_state = 0;
+#endif /* NX_IPSEC_ENABLE */
+
+            /* Clear the IP version.  */
+            packet_ptr -> nx_packet_ip_version  =  0;
+
+            /* Clear the IP identification flag.  */
+            packet_ptr -> nx_packet_identical_copy = NX_FALSE;
+
+            /* Initialize the IP header length. */
+            packet_ptr -> nx_packet_ip_header_length = 0;
+
+            /* Return this block pointer to the suspended thread waiting for
+               a block.  */
+            *((NX_PACKET **)thread_ptr -> tx_thread_additional_suspend_info) =  packet_ptr;
+
+            /* Put return status into the thread control block.  */
+            thread_ptr -> tx_thread_suspend_status =  NX_SUCCESS;
+
+            /* Resume thread.  */
+            _tx_thread_system_resume(thread_ptr);
+        }
+        else
+        {
+
+            /* No thread is suspended for a memory block.  */
+
+            /* Mark the packet as free.  */
+            /*lint -e{923} suppress cast of ULONG to pointer.  */
+            packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next =  (NX_PACKET *)NX_PACKET_FREE;
+
+            /* Put the packet back in the available list.  */
+            packet_ptr -> nx_packet_queue_next =  pool_ptr -> nx_packet_pool_available_list;
+
+            /* Adjust the head pointer.  */
+            pool_ptr -> nx_packet_pool_available_list =  packet_ptr;
+
+            /* Increment the count of available blocks.  */
+            pool_ptr -> nx_packet_pool_available++;
+
+            /* Restore interrupts.  */
+            TX_RESTORE
+        }
+
+#ifndef NX_DISABLE_PACKET_CHAIN
+        /* Move to the next packet in the list.  */
+        packet_ptr =  next_packet;
+    }
+#endif /* NX_DISABLE_PACKET_CHAIN */
+
+    /* Return completion status.  */
+    return(NX_SUCCESS);
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_transmit_release.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_transmit_release.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_packet_transmit_release.c	(revision 69)
@@ -0,0 +1,134 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Packet Pool Management (Packet)                                     */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_packet.h"
+
+#ifdef FEATURE_NX_IPV6
+#include "nx_ipv6.h"
+#endif
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_packet_transmit_release                         PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function releases a transmitted packet chain back to the       */
+/*    appropriate packet pool.  If the packet is a TCP packet, it is      */
+/*    simply marked as completed.  The actual release is deferred to      */
+/*    the TCP component.                                                  */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    packet_ptr                            Pointer of packet to release  */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Completion status             */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_packet_release                    Release packet back to pool   */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nx_packet_transmit_release(NX_PACKET *packet_ptr)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+UINT status;
+
+
+    /* If trace is enabled, insert this event into the trace buffer.  */
+    NX_TRACE_IN_LINE_INSERT(NX_TRACE_PACKET_TRANSMIT_RELEASE, packet_ptr, packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next, (packet_ptr -> nx_packet_pool_owner) -> nx_packet_pool_available, 0, NX_TRACE_PACKET_EVENTS, 0, 0);
+
+    /* Disable interrupts temporarily.  */
+    TX_DISABLE
+
+    /* Add debug information. */
+    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
+
+    /* Determine if the packet is a queued TCP data packet.  Such packets cannot be released
+       immediately, since they may need to be resent.  */
+    /*lint -e{923} suppress cast of ULONG to pointer.  */
+    if ((packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next != ((NX_PACKET *)NX_PACKET_ALLOCATED)) &&
+        (packet_ptr -> nx_packet_union_next.nx_packet_tcp_queue_next != ((NX_PACKET *)NX_PACKET_FREE)))
+    {
+
+        /* Yes, this is indeed a TCP packet.  Just mark this with the NX_DRIVER_TX_DONE
+           value to let the TCP layer know it is no longer queued up.  */
+        /*lint -e{923} suppress cast of ULONG to pointer.  */
+        packet_ptr -> nx_packet_queue_next =  (NX_PACKET *)NX_DRIVER_TX_DONE;
+
+        /* Remove the IP header and adjust the length.  */
+        packet_ptr -> nx_packet_prepend_ptr += packet_ptr -> nx_packet_ip_header_length;
+        packet_ptr -> nx_packet_length -= packet_ptr -> nx_packet_ip_header_length;
+
+        /* Reset the IP header length. */
+        packet_ptr -> nx_packet_ip_header_length = 0;
+
+        /* Restore interrupts.  */
+        TX_RESTORE
+
+        /* Return success.  */
+        status =  NX_SUCCESS;
+    }
+    else
+    {
+
+        /* Restore interrupts.  */
+        TX_RESTORE
+
+        /* Call the actual packet release function.  */
+        status =  _nx_packet_release(packet_ptr);
+    }
+
+    /* Return completion status.  */
+    return(status);
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_system_initialize.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_system_initialize.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_system_initialize.c	(revision 69)
@@ -0,0 +1,272 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   System Management (System)                                          */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Locate NetX system data in this file.  */
+
+#define NX_SYSTEM_INIT
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_system.h"
+#include "nx_packet.h"
+#include "nx_arp.h"
+#include "nx_rarp.h"
+#include "nx_ip.h"
+#include "nx_udp.h"
+#include "nx_icmp.h"
+#include "nx_igmp.h"
+#include "nx_tcp.h"
+
+#ifdef FEATURE_NX_IPV6
+#include "nx_nd_cache.h"
+#endif /* FEATURE_NX_IPV6 */
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_system_initialize                               PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function initializes the various components and system data    */
+/*    structures.                                                         */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    pool_start                            Packet pool starting address  */
+/*    pool_size                             Packet pool size in bytes     */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_packet_pool_initialize            Initialize Packet Pool        */
+/*                                            component                   */
+/*    _nx_ip_initialize                     Initialize IP component       */
+/*    _nx_tcp_initialize                    Initialize TCP component      */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application                                                         */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID  _nx_system_initialize(VOID)
+{
+
+    /* Check whether or not system has been initialized? */
+    if (_nx_system_build_options_1 | _nx_system_build_options_2 |
+        _nx_system_build_options_3 | _nx_system_build_options_4 | _nx_system_build_options_5)
+    {
+
+        /* Yes it is. Just return. */
+        return;
+    }
+
+    /* If trace is enabled, insert this event into the trace buffer.  */
+    NX_TRACE_IN_LINE_INSERT(NX_TRACE_SYSTEM_INITIALIZE, 0, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
+
+    /* Call the packet pool initialization component for NetX.  */
+    _nx_packet_pool_initialize();
+
+    /* Call the IP component initialization.  */
+    _nx_ip_initialize();
+
+    /* Call the TCP component initialization.  */
+    /*lint -e{522} suppress lack of side-effects.  */
+    _nx_tcp_initialize();
+
+    /* Setup the build options variables.  */
+    _nx_system_build_options_1 = 0
+#ifdef NX_LITTLE_ENDIAN
+        | (((ULONG)1) << 31)
+#endif
+#ifdef NX_DISABLE_ARP_AUTO_ENTRY
+        | (((ULONG)1) << 30)
+#endif
+#ifdef NX_ENABLE_TCP_KEEPALIVE
+        | (((ULONG)1) << 29)
+#endif
+#ifdef NX_TCP_IMMEDIATE_ACK
+        | (((ULONG)1) << 28)
+#endif
+#ifdef NX_DRIVER_DEFERRED_PROCESSING
+        | (((ULONG)1) << 27)
+#endif
+#ifdef NX_DISABLE_FRAGMENTATION
+        | (((ULONG)1) << 26)
+#endif
+#ifdef NX_DISABLE_IP_RX_CHECKSUM
+        | (((ULONG)1) << 25)
+#endif
+#ifdef NX_DISABLE_IP_TX_CHECKSUM
+        | (((ULONG)1) << 24)
+#endif
+#ifdef NX_DISABLE_TCP_RX_CHECKSUM
+        | (((ULONG)1) << 23)
+#endif
+#ifdef NX_DISABLE_TCP_TX_CHECKSUM
+        | (((ULONG)1) << 22)
+#endif
+#ifdef NX_DISABLE_RESET_DISCONNECT
+        | (((ULONG)1) << 21)
+#endif
+#ifdef NX_DISABLE_RX_SIZE_CHECKING
+        | (((ULONG)1) << 20)
+#endif
+#ifdef NX_DISABLE_ARP_INFO
+        | (((ULONG)1) << 19)
+#endif
+#ifdef NX_DISABLE_IP_INFO
+        | (((ULONG)1) << 18)
+#endif
+#ifdef NX_DISABLE_ICMP_INFO
+        | (((ULONG)1) << 17)
+#endif
+#ifdef NX_DISABLE_IGMP_INFO
+        | (((ULONG)1) << 16)
+#endif
+#ifdef NX_DISABLE_PACKET_INFO
+        | (((ULONG)1) << 15)
+#endif
+#ifdef NX_DISABLE_RARP_INFO
+        | (((ULONG)1) << 14)
+#endif
+#ifdef NX_DISABLE_TCP_INFO
+        | (((ULONG)1) << 13)
+#endif
+#ifdef NX_DISABLE_UDP_INFO
+        | (((ULONG)1) << 12)
+#endif
+    ;
+
+
+    /* Add the retry shift value to the options.  */
+#if (NX_TCP_RETRY_SHIFT > 0xF)
+    _nx_system_build_options_1 |=  0xF;
+#else
+    _nx_system_build_options_1 |=  NX_TCP_RETRY_SHIFT;
+#endif
+
+#if (NX_IP_PERIODIC_RATE > 0xFFFFUL)
+    _nx_system_build_options_2 =  ((ULONG)0xFFFF0000);
+#else
+    _nx_system_build_options_2 =  ((ULONG)NX_IP_PERIODIC_RATE) << 16;
+#endif
+
+#if (NX_ARP_EXPIRATION_RATE > 0xFF)
+    _nx_system_build_options_2 |=  ((ULONG)0xFF) << 8;
+#else
+    _nx_system_build_options_2 |=  ((ULONG)NX_ARP_EXPIRATION_RATE) << 8;
+#endif
+#if (NX_ARP_UPDATE_RATE > 0xFF)
+    _nx_system_build_options_2 |=  ((ULONG)0xFF);
+#else
+    _nx_system_build_options_2 |=  ((ULONG)NX_ARP_UPDATE_RATE);
+#endif
+
+    /* Setup third option word.  */
+#if (NX_TCP_ACK_TIMER_RATE > 0xFF)
+    _nx_system_build_options_3 =  ((ULONG)0xFF000000);
+#else
+    _nx_system_build_options_3 =  ((ULONG)NX_TCP_ACK_TIMER_RATE) << 24;
+#endif
+#if (NX_TCP_FAST_TIMER_RATE > 0xFF)
+    _nx_system_build_options_3 |=  ((ULONG)0xFF) << 16;
+#else
+    _nx_system_build_options_3 |=  ((ULONG)NX_TCP_FAST_TIMER_RATE) << 16;
+#endif
+#if (NX_TCP_TRANSMIT_TIMER_RATE > 0xFF)
+    _nx_system_build_options_3 |=  ((ULONG)0xFF) << 8;
+#else
+    _nx_system_build_options_3 |=  ((ULONG)NX_TCP_TRANSMIT_TIMER_RATE) << 8;
+#endif
+#if (NX_TCP_KEEPALIVE_RETRY > 0xFF)
+    _nx_system_build_options_3 |=  ((ULONG)0xFF);
+#else
+    _nx_system_build_options_3 |=  ((ULONG)NX_TCP_KEEPALIVE_RETRY);
+#endif
+
+    /* Setup the fourth option word.  */
+#if (NX_TCP_KEEPALIVE_INITIAL > 0xFFFFUL)
+    _nx_system_build_options_4 =  ((ULONG)0xFFFF0000);
+#else
+    _nx_system_build_options_4 =  ((ULONG)NX_TCP_KEEPALIVE_INITIAL) << 16;
+#endif
+#if (NX_ARP_MAXIMUM_RETRIES > 0xFF)
+    _nx_system_build_options_4 |=  ((ULONG)0xFF) << 8;
+#else
+    _nx_system_build_options_4 |=  ((ULONG)NX_ARP_MAXIMUM_RETRIES) << 8;
+#endif
+#if (NX_ARP_MAX_QUEUE_DEPTH > 0xF)
+    _nx_system_build_options_4 |=  ((ULONG)0xF) << 4;
+#else
+    _nx_system_build_options_4 |=  ((ULONG)NX_ARP_MAX_QUEUE_DEPTH) << 4;
+#endif
+#if (NX_TCP_KEEPALIVE_RETRIES > 0xF)
+    _nx_system_build_options_4 |=  ((ULONG)0xF);
+#else
+    _nx_system_build_options_4 |=  ((ULONG)NX_TCP_KEEPALIVE_RETRIES);
+#endif
+
+    /* Setup the fifth option word.  */
+#if (NX_MAX_MULTICAST_GROUPS > 0xFF)
+    _nx_system_build_options_5 =  ((ULONG)0xFF000000);
+#else
+    _nx_system_build_options_5 =  ((ULONG)NX_MAX_MULTICAST_GROUPS) << 24;
+#endif
+#if (NX_MAX_LISTEN_REQUESTS > 0xFF)
+    _nx_system_build_options_5 |=  ((ULONG)0xFF) << 16;
+#else
+    _nx_system_build_options_5 |=  ((ULONG)NX_MAX_LISTEN_REQUESTS) << 16;
+#endif
+#if (NX_TCP_MAXIMUM_RETRIES > 0xFF)
+    _nx_system_build_options_5 |=  ((ULONG)0xFF) << 8;
+#else
+    _nx_system_build_options_5 |=  ((ULONG)NX_TCP_MAXIMUM_RETRIES) << 8;
+#endif
+#if (NX_TCP_MAXIMUM_TX_QUEUE > 0xFF)
+    _nx_system_build_options_5 |=  ((ULONG)0xFF);
+#else
+    _nx_system_build_options_5 |=  ((ULONG)NX_TCP_MAXIMUM_TX_QUEUE);
+#endif
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_tcp_initialize.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_tcp_initialize.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nx_tcp_initialize.c	(revision 69)
@@ -0,0 +1,79 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Transmission Control Protocol (TCP)                                 */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Locate NetX global TCP Component data in this file.  */
+
+#define NX_TCP_INIT
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_tcp.h"
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nx_tcp_initialize                                  PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function initializes the TCP management component.             */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_system_initialize                 System initialization         */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID  _nx_tcp_initialize(VOID)
+{
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_find_max_prefix_length.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_find_max_prefix_length.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_find_max_prefix_length.c	(revision 69)
@@ -0,0 +1,123 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol version 6 Default Router Table (IPv6 router)      */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+#define NX_SOURCE_CODE
+
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+
+#ifdef FEATURE_NX_IPV6
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nxd_ipv6_find_max_prefix_length                    PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function finds the longest matching prefix between two IPv6    */
+/*      addresses.                                                        */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    addr1                                 IPv6 address 1                */
+/*    addr2                                 IPv6 address 2                */
+/*    max_length                            Maximum length to match       */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    Number of matching bits                                             */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ipv6_source_selection                                           */
+/*                                                                        */
+/*  NOTE                                                                  */
+/*                                                                        */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT _nxd_ipv6_find_max_prefix_length(ULONG *addr1, ULONG *addr2, UINT max_length)
+{
+UINT length = 0;
+UINT i, j, bit, time;
+
+    for (i = 0; i < 4; i++)
+    {
+        if (addr1[i] == addr2[i])
+        {
+            length += 32;
+        }
+        /* Length shall not exceed max_length. Stop compare. */
+        else if (length + 31 < max_length)
+        {
+            break;
+        }
+        else
+        {
+            bit = 16;
+            time = 16;
+            for (j = 0; j < 5; j++)
+            {
+                time = time / 2;
+                if (addr1[i] >> bit == addr2[i] >> bit)
+                {
+                    bit -= time;
+                    if (time == 0)
+                    {
+                        length += (32 - bit);
+                    }
+                }
+                else if (j == 4)
+                {
+                    length += (31 - bit);
+                    break;
+                }
+                else
+                {
+                    bit += time;
+                }
+            }
+            break;
+        }
+    }
+
+
+    return(length);
+}
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_interface_find.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_interface_find.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_interface_find.c	(revision 69)
@@ -0,0 +1,327 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+
+#ifdef FEATURE_NX_IPV6
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nxd_ipv6_interface_find                            PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function finds a suitable outgoing interface based on the      */
+/*    destination IP address.                                             */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    dest_address                          Destination IP address        */
+/*    ipv6_interface_index                  Index interface to use as the */
+/*                                            outgoing  interface.        */
+/*    ipv6_address_index                    Address index to use as the   */
+/*                                            source address              */
+/*    if_ptr                                Outgoing interface if not null*/
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                                              */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Internal function.                                                  */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT _nxd_ipv6_interface_find(NX_IP *ip_ptr, ULONG *dest_address,
+                              NXD_IPV6_ADDRESS **ipv6_addr, NX_INTERFACE *if_ptr)
+{
+
+UINT                          i;
+NXD_IPV6_ADDRESS             *ipv6_address;
+NX_IPV6_DEFAULT_ROUTER_ENTRY *rt_entry;
+UINT                          start_index;
+UINT                          end_index;
+ULONG                         address_type = IPv6_Address_Type(dest_address);
+
+    /* ipv6_addr must not be NULL. */
+    NX_ASSERT(ipv6_addr != NX_NULL);
+
+#ifdef NX_ENABLE_IPV6_MULTICAST
+    /* Check for a multicast destination address.*/
+    if (address_type & IPV6_ADDRESS_MULTICAST)
+    {
+
+
+        /* Search the address whether match our mld join list.  */
+        for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++)
+        {
+
+            /* Skip empty entries. */
+            if (ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_interface_list == NX_NULL)
+            {
+                continue;
+            }
+
+            /* Skip not matched interface. */
+            if (if_ptr && (ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_interface_list != if_ptr))
+            {
+                continue;
+            }
+
+            /* Skip multicast entry whose related interface is down. */
+            if (ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_interface_list -> nx_interface_link_up == NX_FALSE)
+            {
+                continue;
+            }
+
+            if (CHECK_IPV6_ADDRESSES_SAME(ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_list, dest_address))
+            {
+                *ipv6_addr = ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_interface_list -> nxd_interface_ipv6_address_list_head;
+
+                /* Check whether there's address on the interface. */
+                if (*ipv6_addr == NX_NULL)
+                {
+                    return(NX_NO_INTERFACE_ADDRESS);
+                }
+
+                /* The address must be valid in list queue of interface. */
+                NX_ASSERT((*ipv6_addr) -> nxd_ipv6_address_valid);
+                return(NX_SUCCESS);
+            }
+        }
+    }
+#endif /* NX_ENABLE_IPV6_MULTICAST  */
+
+    /* Loop through addresses. */
+    if (address_type & IPV6_ADDRESS_UNICAST)
+    {
+
+        /* Unicast address. Is the destination one of local address? */
+        for (i = 0; i < NX_MAX_IPV6_ADDRESSES; i++)
+        {
+
+            /* Compare the address. */
+            if ((ip_ptr -> nx_ipv6_address[i].nxd_ipv6_address_valid) &&
+                (CHECK_IPV6_ADDRESSES_SAME(ip_ptr -> nx_ipv6_address[i].nxd_ipv6_address, dest_address)))
+            {
+
+                /* Found a proper address. */
+                *ipv6_addr = &(ip_ptr -> nx_ipv6_address[i]);
+                return(NX_SUCCESS);
+            }
+        }
+    }
+
+    if (if_ptr)
+    {
+
+        /* Search addresses from specified interface only. */
+        start_index = if_ptr -> nx_interface_index;
+        end_index = (UINT)(if_ptr -> nx_interface_index + 1);
+    }
+    else
+    {
+
+        /* Search addressed from all interfaces. */
+        start_index = 0;
+        end_index = NX_MAX_PHYSICAL_INTERFACES;
+    }
+
+    /* Loop through interfaces. */
+    for (i = start_index; i < end_index; i++)
+    {
+
+        /* Skip interface which is down. */
+        if (ip_ptr -> nx_ip_interface[i].nx_interface_link_up == NX_FALSE)
+        {
+            continue;
+        }
+
+        /* Point to the first address unit in the interface. */
+        for (ipv6_address = ip_ptr -> nx_ip_interface[i].nxd_interface_ipv6_address_list_head;
+             ipv6_address;
+             ipv6_address = ipv6_address -> nxd_ipv6_address_next)
+        {
+
+            /* Skip address that is not valid. */
+            if (ipv6_address -> nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_VALID)
+            {
+                continue;
+            }
+
+            if (address_type & IPV6_ADDRESS_LINKLOCAL)
+            {
+
+                /* Destination address is link local. */
+                if (IPv6_Address_Type(ipv6_address -> nxd_ipv6_address) & IPV6_ADDRESS_LINKLOCAL)
+                {
+
+                    /* Found link local address as source. */
+                    break;
+                }
+            }
+            else if (_nxd_ipv6_find_max_prefix_length(dest_address, ipv6_address -> nxd_ipv6_address,
+                                                      ipv6_address -> nxd_ipv6_address_prefix_length) >=
+                     ipv6_address -> nxd_ipv6_address_prefix_length)
+            {
+
+                /* Found a proper outgoing address. */
+                break;
+            }
+            /* Check for a multicast destination address.*/
+            else if (address_type & IPV6_ADDRESS_MULTICAST)
+            {
+
+                /* This indicates a global IP multicast. */
+                /* So we need to make a best guess at the
+                   address index of the host global address. */
+
+                /* Determine(LLA vs Global IP address type from the higher order bytes. */
+                if ((dest_address[0] & 0x000F0000) == 0x00020000)
+                {
+
+                    /* Check for a link local IP address. */
+                    if (IPv6_Address_Type(ipv6_address -> nxd_ipv6_address) & IPV6_ADDRESS_LINKLOCAL)
+                    {
+
+                        /* This will do! */
+                        break;
+                    }
+                }
+                /* Check for a global IP address. */
+                else if (IPv6_Address_Type(ipv6_address -> nxd_ipv6_address) & IPV6_ADDRESS_GLOBAL)
+                {
+
+                    /* This will do! */
+                    break;
+                }
+            }
+        }
+
+        if (ipv6_address)
+        {
+
+            /* Found a proper address. */
+            *ipv6_addr = ipv6_address;
+            return(NX_SUCCESS);
+        }
+    }
+
+#ifndef NX_DISABLE_LOOPBACK_INTERFACE
+    /* Get ipv6 address in the loop back interface. */
+    ipv6_address = ip_ptr -> nx_ip_interface[NX_LOOPBACK_INTERFACE].nxd_interface_ipv6_address_list_head;
+    if (ipv6_address)
+    {
+
+        /* Check whether the destination is loop back address. */
+        if (CHECK_IPV6_ADDRESSES_SAME(ipv6_address -> nxd_ipv6_address, dest_address))
+        {
+            *ipv6_addr = ipv6_address;
+            return(NX_SUCCESS);
+        }
+    }
+#endif /* NX_DISABLE_LOOPBACK_INTERFACE */
+
+    /* Is the destination address gloabl? */
+    if (address_type & IPV6_ADDRESS_GLOBAL)
+    {
+
+        /* Yes. Check default router. */
+        for (i = 0; i < NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE; i++)
+        {
+
+            rt_entry = &ip_ptr -> nx_ipv6_default_router_table[i];
+
+            /* Skip invalid entries. */
+            if (rt_entry -> nx_ipv6_default_router_entry_flag == 0)
+            {
+                continue;
+            }
+
+            /* Skip interface which is down. */
+            if (rt_entry -> nx_ipv6_default_router_entry_interface_ptr -> nx_interface_link_up == NX_FALSE)
+            {
+                continue;
+            }
+
+            /* Skip not matched interface. */
+            if (if_ptr && (rt_entry -> nx_ipv6_default_router_entry_interface_ptr != if_ptr))
+            {
+                continue;
+            }
+
+            /* Get first address from interface. */
+            ipv6_address = rt_entry -> nx_ipv6_default_router_entry_interface_ptr -> nxd_interface_ipv6_address_list_head;
+
+            while (ipv6_address)
+            {
+
+                /* Check for a valid address. */
+                if (ipv6_address -> nxd_ipv6_address_state != NX_IPV6_ADDR_STATE_VALID)
+                {
+                    ipv6_address = ipv6_address -> nxd_ipv6_address_next;
+                }
+                /* Check for link-local address. */
+                else if (IPv6_Address_Type(ipv6_address -> nxd_ipv6_address) & IPV6_ADDRESS_LINKLOCAL)
+                {
+                    ipv6_address = ipv6_address -> nxd_ipv6_address_next;
+                }
+                else
+                {
+                    *ipv6_addr = ipv6_address;
+
+                    /* Found global address as link-local address. */
+                    return(NX_SUCCESS);
+                }
+            }
+        }
+    }
+
+    /* No available interface. */
+    return(NX_NO_INTERFACE_ADDRESS);
+}
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_prefix_router_timer_tick.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_prefix_router_timer_tick.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_prefix_router_timer_tick.c	(revision 69)
@@ -0,0 +1,182 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol version 6 Default Router Table (IPv6 router)      */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_nd_cache.h"
+#include "nx_icmpv6.h"
+
+
+#ifdef FEATURE_NX_IPV6
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nxd_ipv6_prefix_router_timer_tick                   PORTABLE C     */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    At every time tick, this function checks for time out expiration on */
+/*    both the default router list and the prefix list tables bound to the*/
+/*    supplied IP instance.                                               */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                IP instance pointer           */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_invalidate_destination_entry    Invalidate the entry in the     */
+/*                                           destination                  */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_ip_thread_entry                                                 */
+/*                                                                        */
+/*  NOTE                                                                  */
+/*                                                                        */
+/*    The nx_ip_protection mutex must be obtained before calling this     */
+/*    function.                                                           */
+/*                                                                        */
+/*    This function cannot be called from ISR.                            */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+VOID _nxd_ipv6_prefix_router_timer_tick(NX_IP *ip_ptr)
+{
+
+UINT                          i, table_size;
+NX_IPV6_PREFIX_ENTRY         *tmp, *prefix_entry;
+NX_IPV6_DEFAULT_ROUTER_ENTRY *rt_entry;
+
+
+    /* Set a local variable for convenience. */
+    table_size = ip_ptr -> nx_ipv6_default_router_table_size;
+
+    /* Check each entry in the default router table. */
+    for (i = 0; table_size && (i < NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE); i++)
+    {
+
+        /* Set a local variable for convenience. */
+        rt_entry = &ip_ptr -> nx_ipv6_default_router_table[i];
+
+        /* Skip invalid or empty slots. */
+        if ((rt_entry -> nx_ipv6_default_router_entry_flag & NX_IPV6_ROUTE_TYPE_VALID) == 0)
+        {
+            continue;
+        }
+
+        /* Keep track of valid entries we've checked. */
+        table_size--;
+
+        /* Has the entry on the current table entry expired? */
+        if (rt_entry -> nx_ipv6_default_router_entry_life_time == 0)
+        {
+
+            /* Yes, the router has timed out. */
+            /* Does this router have an entry in the ND cache table? */
+            if (rt_entry -> nx_ipv6_default_router_entry_neighbor_cache_ptr)
+            {
+
+                /* Yes, clear out that entry, we are invalidating this entry. */
+                rt_entry -> nx_ipv6_default_router_entry_neighbor_cache_ptr -> nx_nd_cache_is_router = NX_NULL;
+            }
+
+            /* Clean any entries in the destination table for this router.  */
+            _nx_invalidate_destination_entry(ip_ptr, rt_entry -> nx_ipv6_default_router_entry_router_address);
+
+            /* Invalidate the entry in the router table. */
+            rt_entry -> nx_ipv6_default_router_entry_flag = 0;
+
+            /* Clear the interface pointer .*/
+            rt_entry -> nx_ipv6_default_router_entry_interface_ptr = NX_NULL;
+
+            /* Decrease the IP instance default router count. */
+            ip_ptr -> nx_ipv6_default_router_table_size--;
+        }
+        else
+        {
+            /* Is this a static router (infinite timeout)? */
+            if (rt_entry -> nx_ipv6_default_router_entry_life_time != 0xFFFF)
+            {
+
+                /* No, so decrement the lifetime by one tick.*/
+                rt_entry -> nx_ipv6_default_router_entry_life_time--;
+            }
+        }
+    }
+
+    /* Set a pointer to the first prefix entry in the IP prefix list. */
+    prefix_entry = ip_ptr -> nx_ipv6_prefix_list_ptr;
+
+    /* Loop through the entire list. */
+    while (prefix_entry)
+    {
+
+        /* Set a placemarker at the current prefix. */
+        tmp = prefix_entry;
+
+        /* Get a pointer to the next prefix. */
+        prefix_entry = prefix_entry -> nx_ipv6_prefix_entry_next;
+
+        /* Skip the static entries. */
+        if (tmp -> nx_ipv6_prefix_entry_valid_lifetime != (UINT)0xFFFFFFFF)
+        {
+
+            /* Has the prefix entry timeout expired? */
+            if (tmp -> nx_ipv6_prefix_entry_valid_lifetime == 0)
+            {
+
+                /* Yes, so delete it from the list. */
+                _nx_ipv6_prefix_list_delete_entry(ip_ptr, tmp);
+            }
+            else
+            {
+
+                /* Just decrement the time remaining. */
+                tmp -> nx_ipv6_prefix_entry_valid_lifetime--;
+            }
+        }
+    }
+
+    return;
+}
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_router_lookup.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_router_lookup.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_router_lookup.c	(revision 69)
@@ -0,0 +1,206 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol version 6 Default Router Table (IPv6 router)      */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_nd_cache.h"
+#include "nx_icmpv6.h"
+
+
+#ifdef FEATURE_NX_IPV6
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nxd_ipv6_router_lookup                             PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function finds a valid router from the default router table,   */
+/*    and this function also return the pointer to the router's cache     */
+/*    entry in the NetX Duo cache table.                                  */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                IP instance pointer           */
+/*    if_ptr                                Pointer to interface          */
+/*    router_address                        Pointer to default router     */
+/*    nd_cache_entry                        Pointer to associated ND entry*/
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Non zero status               */
+/*                                            router not found            */
+/*                                          Zero status, router found     */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    _nx_icmpv6_process_redirect                                         */
+/*    _nx_ipv6_packet_send                                                */
+/*                                                                        */
+/*  NOTE                                                                  */
+/*                                                                        */
+/*    Internal Function.  Caller must have acquired IP protection mutex.  */
+/*    This function should not be called from ISR.  Although it has no    */
+/*    blocking calls it will slow down response time.                     */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nxd_ipv6_router_lookup(NX_IP *ip_ptr, NX_INTERFACE *if_ptr, ULONG *router_address, void **nd_cache_entry)
+{
+
+UINT                          i;
+UINT                          table_size;
+UINT                          routers_checked;
+NX_IPV6_DEFAULT_ROUTER_ENTRY *rt_entry;
+ND_CACHE_ENTRY               *NDCacheEntry;
+
+    NX_ASSERT(nd_cache_entry != NX_NULL)
+
+    /* Initialize cache pointer to NULL (if no router found). */
+    *nd_cache_entry = NULL;
+
+    /* Set a local variable for convenience. */
+    table_size = ip_ptr -> nx_ipv6_default_router_table_size;
+
+    /* Check if there have been any routers added to the table. */
+    if (table_size == 0)
+    {
+
+        /* Return a non zero (e.g. unsuccessful) error status. */
+        return(NX_NOT_SUCCESSFUL);
+    }
+
+    /* Loop to check the router table.  */
+    for (i = 0; table_size && (i < NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE); i++)
+    {
+
+        /* Local pointer for convenience. */
+        rt_entry = &(ip_ptr -> nx_ipv6_default_router_table[i]);
+
+        /* Does this slot contain a valid router? */
+        if ((rt_entry -> nx_ipv6_default_router_entry_flag & NX_IPV6_ROUTE_TYPE_VALID) &&
+            (rt_entry -> nx_ipv6_default_router_entry_interface_ptr == if_ptr))
+        {
+
+            /* Keep track of valid entries we have checked. */
+            NDCacheEntry = rt_entry -> nx_ipv6_default_router_entry_neighbor_cache_ptr;
+
+            /* Is this router reachable? */
+            if (!NDCacheEntry ||
+                (NDCacheEntry -> nx_nd_cache_nd_status < ND_CACHE_STATE_REACHABLE) ||
+                (NDCacheEntry -> nx_nd_cache_nd_status > ND_CACHE_STATE_PROBE))
+            {
+
+                /* No, skip over. */
+                table_size--;
+                continue;
+            }
+
+            /* Yes, copy this router address into the return pointer. */
+            COPY_IPV6_ADDRESS(ip_ptr -> nx_ipv6_default_router_table[i].nx_ipv6_default_router_entry_router_address, router_address);
+
+            /* Copy the router's cache entry pointer to the supplied cache table pointer. */
+            *nd_cache_entry = ip_ptr -> nx_ipv6_default_router_table[i].nx_ipv6_default_router_entry_neighbor_cache_ptr;
+
+            /* We're done. Break out of the search. */
+            return(NX_SUCCESS);
+        }
+    }
+
+    /* If we are here, we did not find a suitable default router. Do a search
+       of routers previously reachable. */
+
+    /* Start at the round robin index so we don't always choose the first
+       less-than-reachable router in the table. */
+    i = ip_ptr -> nx_ipv6_default_router_table_round_robin_index;
+
+    /* Find a router with previously known reachability. */
+    for (routers_checked = 0; routers_checked < NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE; routers_checked++)
+    {
+
+        /* Local pointer for convenience. */
+        rt_entry = &(ip_ptr -> nx_ipv6_default_router_table[i]);
+
+        /* Does this slot contain a valid router? */
+        if ((rt_entry -> nx_ipv6_default_router_entry_flag & NX_IPV6_ROUTE_TYPE_VALID) &&
+            (rt_entry -> nx_ipv6_default_router_entry_interface_ptr == if_ptr))
+        {
+
+            /* Yes, copy this router to the return pointer. */
+            COPY_IPV6_ADDRESS(rt_entry -> nx_ipv6_default_router_entry_router_address, router_address);
+
+            /* Copy the router's cache entry pointer to the supplied cache table pointer. */
+            *nd_cache_entry = rt_entry -> nx_ipv6_default_router_entry_neighbor_cache_ptr;
+
+            /* Update the index so the same router is not chosen again if there
+               any other less-than-reachable routers we can choose, RFC 2461 6.3.6. */
+            ip_ptr -> nx_ipv6_default_router_table_round_robin_index++;
+
+            /* Do we need wrap the index? */
+            if (ip_ptr -> nx_ipv6_default_router_table_round_robin_index == NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE)
+            {
+
+                /* Yes, start back at the first slot. */
+                ip_ptr -> nx_ipv6_default_router_table_round_robin_index = 0;
+            }
+
+            /* We're done. Return successful outcome status. */
+            return(NX_SUCCESS);
+        }
+
+        /* Are we past the end of the table? */
+        if (i == NX_IPV6_DEFAULT_ROUTER_TABLE_SIZE - 1)
+        {
+            /* Yes, wrap to the first slot.*/
+            i = 0;
+        }
+        else
+        {
+            i++;
+        }
+    }
+
+    /* Router not found. */
+    return(NX_NOT_SUCCESSFUL);
+}
+
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_router_solicitation_check.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_router_solicitation_check.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_router_solicitation_check.c	(revision 69)
@@ -0,0 +1,122 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol version 6 Default Router Table (IPv6 router)      */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_nd_cache.h"
+#include "nx_icmpv6.h"
+
+
+#ifdef FEATURE_NX_IPV6
+
+#ifndef NX_DISABLE_ICMPV6_ROUTER_SOLICITATION
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nxd_ipv6_router_solicitation_check                 PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    At every time tick, this function decrement the router solicitation */
+/*    counter.   When the counter reaches zero, the stack sends out       */
+/*    router solicitation.                                                */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                IP instance pointer           */
+/*    router_address                        The specific gateway address  */
+/*                                            to search for.              */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    None                                                                */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_icmpv6_send_rs                   Send router solicitation packet*/
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    nx_ip_thread_entry                    Handle IP thread task events  */
+/*                                                                        */
+/*  NOTE                                                                  */
+/*                                                                        */
+/*    Caller must obtain nx_ip_protection mutex before calling this       */
+/*    function.                                                           */
+/*                                                                        */
+/*    This function cannot be called from ISR.                            */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+void _nxd_ipv6_router_solicitation_check(NX_IP *ip_ptr)
+{
+UINT i;
+
+    for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
+    {
+        if (ip_ptr -> nx_ip_interface[i].nx_interface_valid == NX_TRUE)
+        {
+
+            /* Check if max number of router solicitation messages have been sent. */
+            if (ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_count != 0)
+            {
+
+                /* Check on count down timer for sending out next router solicitation message. */
+                ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_timer--;
+                if (ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_timer == 0)
+                {
+                    if (_nx_icmpv6_send_rs(ip_ptr, i) &&
+                        (ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_count ==
+                         ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_max))
+                    {
+
+                        /* Initial RS is not sent successfully. */
+                        /* Try it next round. */
+                        ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_timer = 1;
+                    }
+                    else
+                    {
+                        ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_count--;
+                        ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_timer = ip_ptr -> nx_ip_interface[i].nx_ipv6_rtr_solicitation_interval;
+                    }
+                }
+            }
+        }
+    }
+}
+#endif /* NX_DISABLE_ICMPV6_ROUTER_SOLICITATION */
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_search_onlink.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_search_onlink.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxd_ipv6_search_onlink.c	(revision 69)
@@ -0,0 +1,141 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol version 6 Default Router Table (IPv6 router)      */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ipv6.h"
+#include "nx_nd_cache.h"
+
+
+#ifdef FEATURE_NX_IPV6
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nxd_ipv6_search_onlink                              PORTABLE C     */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function checks whether a given IP address is on link.         */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                IP instance                   */
+/*    dest_addr                             The destination address to    */
+/*                                             be checked.                */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                0: Address is not onlink      */
+/*                                          1: Address is onlink          */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    NONE                                                                */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    nx_ipv6_packet_send                  Sends IPv6 packets from upper  */
+/*                                           layer to remote host         */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+INT _nxd_ipv6_search_onlink(NX_IP *ip_ptr, ULONG *dest_addr)
+{
+
+UINT                  addr_index;
+NX_IPV6_PREFIX_ENTRY *prefix_entry;
+NXD_IPV6_ADDRESS     *ipv6_address;
+
+
+    /* First special case is the link local address. All these
+       addresses are onlink.  */
+    if (IPv6_Address_Type(dest_addr) & IPV6_ADDRESS_LINKLOCAL)
+    {
+        return(1);
+    }
+
+    /* Set a local pointer for convenience. */
+    prefix_entry = ip_ptr -> nx_ipv6_prefix_list_ptr;
+
+    /* Loop through the prefix table. Prefixes are the IPv6 equivalent of
+       network domains in IPv4.  */
+    while (prefix_entry)
+    {
+
+        /* Check whether or not the destination address is matched. */
+        if (CHECK_IP_ADDRESSES_BY_PREFIX(dest_addr,
+                                         prefix_entry -> nx_ipv6_prefix_entry_network_address,
+                                         prefix_entry -> nx_ipv6_prefix_entry_prefix_length))
+        {
+            return(1);
+        }
+
+        /* No match. Try the next prefix. */
+        prefix_entry = prefix_entry -> nx_ipv6_prefix_entry_next;
+    }
+
+    /* If no matches found in the prefix list, search the manually configured IPv6 interface addresses. */
+    for (addr_index = 0; addr_index < NX_MAX_IPV6_ADDRESSES; addr_index++)
+    {
+
+        ipv6_address = &ip_ptr -> nx_ipv6_address[addr_index];
+        /* Skip invalid entries. */
+        if (!(ipv6_address -> nxd_ipv6_address_valid))
+        {
+            continue;
+        }
+
+        /* Skip non-manually configured entires. */
+        if (ipv6_address -> nxd_ipv6_address_ConfigurationMethod != NX_IPV6_ADDRESS_MANUAL_CONFIG)
+        {
+            continue;
+        }
+
+        /* Check whether or not the destination address is matched. */
+        if (CHECK_IP_ADDRESSES_BY_PREFIX(dest_addr,
+                                         ipv6_address -> nxd_ipv6_address,
+                                         ipv6_address -> nxd_ipv6_address_prefix_length))
+        {
+            return(1);
+        }
+    }
+
+
+    /* No matches found. Not an onlink address. */
+    return(0);
+}
+
+#endif /* FEATURE_NX_IPV6 */
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxe_ip_create.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxe_ip_create.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxe_ip_create.c	(revision 69)
@@ -0,0 +1,191 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Internet Protocol (IP)                                              */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_ip.h"
+#include "nx_packet.h"
+
+/* Bring in externs for caller checking code.  */
+
+NX_CALLER_CHECKING_EXTERNS
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nxe_ip_create                                      PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function checks for errors in the IP instance create           */
+/*    function call.                                                      */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    ip_ptr                                Pointer to IP control block   */
+/*    name                                  Name of this IP instance      */
+/*    ip_address                            Internet address for this IP  */
+/*    network_mask                          Network mask for IP address   */
+/*    default_pool                          Default packet pool           */
+/*    ip_link_driver                        User supplied IP link driver  */
+/*    memory_ptr                            Pointer memory area for IP    */
+/*    memory_size                           Size of IP memory area        */
+/*    priority                              Priority of IP helper thread  */
+/*    ip_control_block_size                 Size of NX_IP structure       */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Completion status             */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_ip_create                         Actual IP instance create     */
+/*                                            function                    */
+/*    tx_thread_identify                    Get current thread pointer    */
+/*    tx_thread_preemption_change           Change preemption for thread  */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application                                                         */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nxe_ip_create(NX_IP *ip_ptr, CHAR *name, ULONG ip_address, ULONG network_mask,
+                     NX_PACKET_POOL *default_pool, VOID (*ip_link_driver)(struct NX_IP_DRIVER_STRUCT *),
+                     VOID *memory_ptr, ULONG memory_size, UINT priority, UINT ip_control_block_size)
+{
+
+UINT       status;
+UINT       old_threshold = 0;
+NX_IP     *created_ip;
+ULONG      created_count;
+UCHAR     *end_stack;
+TX_THREAD *current_thread;
+
+
+    /* Check for invalid input pointers.  */
+    if ((ip_ptr == NX_NULL) || (default_pool == NX_NULL) ||
+        (default_pool -> nx_packet_pool_id != NX_PACKET_POOL_ID) || (ip_link_driver == NX_NULL) ||
+        (memory_ptr == NX_NULL) || (ip_control_block_size != (UINT)sizeof(NX_IP)))
+    {
+        return(NX_PTR_ERROR);
+    }
+
+    /* Check for a memory size error.  */
+    if (memory_size < TX_MINIMUM_STACK)
+    {
+        return(NX_SIZE_ERROR);
+    }
+
+    /* Check the priority specified.  */
+    if (priority >= TX_MAX_PRIORITIES)
+    {
+        return(NX_OPTION_ERROR);
+    }
+
+    /* Calculate the end of the stack area.  */
+    end_stack =  ((UCHAR *)memory_ptr) + (memory_size - 1);
+
+    /* Pickup current thread pointer.  */
+    current_thread =  tx_thread_identify();
+
+    /* Disable preemption temporarily.  */
+    if (current_thread)
+    {
+        tx_thread_preemption_change(current_thread, 0, &old_threshold);
+    }
+
+    /* Loop to check for the IP instance already created.  */
+    created_ip =     _nx_ip_created_ptr;
+    created_count =  _nx_ip_created_count;
+    while (created_count--)
+    {
+
+        /* Is the new ip already created?  */
+        /*lint -e{946} suppress pointer subtraction, since it is necessary. */
+        if ((ip_ptr == created_ip) ||
+            ((memory_ptr >= created_ip -> nx_ip_thread.tx_thread_stack_start) && (memory_ptr < created_ip -> nx_ip_thread.tx_thread_stack_end)) ||
+            ((((VOID *)end_stack)  >= created_ip -> nx_ip_thread.tx_thread_stack_start) && (((VOID *)end_stack)  < created_ip -> nx_ip_thread.tx_thread_stack_end)))
+        {
+
+            /* Restore preemption.  */
+            if (current_thread)
+            {
+
+                /*lint -e{644} suppress variable might not be initialized, since "old_threshold" was initialized by previous tx_thread_preemption_change. */
+                tx_thread_preemption_change(current_thread, old_threshold, &old_threshold);
+            }
+
+            /* Duplicate ip created, return an error!  */
+            return(NX_PTR_ERROR);
+        }
+
+        /* Move to next entry.  */
+        created_ip =  created_ip -> nx_ip_created_next;
+    }
+
+    /* Restore preemption.  */
+    if (current_thread)
+    {
+
+        /*lint -e{644} suppress variable might not be initialized, since "old_threshold" was initialized by previous tx_thread_preemption_change. */
+        tx_thread_preemption_change(current_thread, old_threshold, &old_threshold);
+    }
+
+    /* Check for invalid IP address.  Note that Interface with DHCP enabled
+       would start with 0.0.0.0.  Therefore the 0 IP address is allowed. */
+    if ((ip_address != 0) &&
+        ((ip_address & NX_IP_CLASS_A_MASK) != NX_IP_CLASS_A_TYPE) &&
+        ((ip_address & NX_IP_CLASS_B_MASK) != NX_IP_CLASS_B_TYPE) &&
+        ((ip_address & NX_IP_CLASS_C_MASK) != NX_IP_CLASS_C_TYPE))
+    {
+        return(NX_IP_ADDRESS_ERROR);
+    }
+
+    /* Check for appropriate caller.  */
+    NX_INIT_AND_THREADS_CALLER_CHECKING
+
+    /* Call actual IP instance create function.  */
+    status =  _nx_ip_create(ip_ptr, name, ip_address, network_mask, default_pool, ip_link_driver,
+                            memory_ptr, memory_size, priority);
+
+    /* Return completion status.  */
+    return(status);
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxe_packet_pool_create.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxe_packet_pool_create.c	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/common/src/nxe_packet_pool_create.c	(revision 69)
@@ -0,0 +1,198 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Packet Pool Management (Packet)                                     */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+#define NX_SOURCE_CODE
+
+
+/* Include necessary system files.  */
+
+#include "nx_api.h"
+#include "nx_packet.h"
+
+/* Bring in externs for caller checking code.  */
+
+NX_CALLER_CHECKING_EXTERNS
+
+
+/**************************************************************************/
+/*                                                                        */
+/*  FUNCTION                                               RELEASE        */
+/*                                                                        */
+/*    _nxe_packet_pool_create                             PORTABLE C      */
+/*                                                           6.1          */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */
+/*                                                                        */
+/*    This function checks for errors in the packet pool create           */
+/*    function call.                                                      */
+/*                                                                        */
+/*  INPUT                                                                 */
+/*                                                                        */
+/*    pool_ptr                              Packet Pool control block     */
+/*    name_ptr                              Packet Pool string pointer    */
+/*    payload_size                          Size of packet payload        */
+/*    pool_start                            Starting address of pool      */
+/*    pool_size                             Number of bytes in pool       */
+/*    pool_control_block_size               Size of packet pool control   */
+/*                                            block                       */
+/*                                                                        */
+/*  OUTPUT                                                                */
+/*                                                                        */
+/*    status                                Completion status             */
+/*                                                                        */
+/*  CALLS                                                                 */
+/*                                                                        */
+/*    _nx_packet_pool_create                Actual packet pool create     */
+/*                                            function                    */
+/*    tx_thread_identify                    Get current thread pointer    */
+/*    tx_thread_preemption_change           Change preemption for thread  */
+/*                                                                        */
+/*  CALLED BY                                                             */
+/*                                                                        */
+/*    Application Code                                                    */
+/*                                                                        */
+/*  RELEASE HISTORY                                                       */
+/*                                                                        */
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),          */
+/*                                            resulting in version 6.1    */
+/*                                                                        */
+/**************************************************************************/
+UINT  _nxe_packet_pool_create(NX_PACKET_POOL *pool_ptr, CHAR *name_ptr, ULONG payload_size,
+                              VOID *pool_start, ULONG pool_size, UINT pool_control_block_size)
+{
+
+UINT            status;
+ULONG           rounded_payload_size;
+ULONG           rounded_pool_size;
+ULONG           header_size;
+UINT            old_threshold = 0;
+NX_PACKET_POOL *created_pool;
+ULONG           created_count;
+CHAR           *end_memory;
+CHAR           *created_end;
+CHAR           *payload_address;
+VOID           *rounded_pool_start;
+TX_THREAD      *current_thread;
+
+
+    /* Check for invalid input pointers.  */
+    if ((pool_ptr == NX_NULL) || (pool_start == NX_NULL) || (pool_control_block_size != (UINT)sizeof(NX_PACKET_POOL)))
+    {
+        return(NX_PTR_ERROR);
+    }
+
+    /* Align the starting address to four bytes. */
+    /*lint -e{923} suppress cast between ULONG and pointer.  */
+    rounded_pool_start = (VOID *)((((ALIGN_TYPE)pool_start + NX_PACKET_ALIGNMENT  - 1) / NX_PACKET_ALIGNMENT) * NX_PACKET_ALIGNMENT);
+
+    /* Round the pool size down to something that is evenly divisible by alignment.  */
+    /*lint -e{923} suppress cast between ULONG and pointer.  */
+    rounded_pool_size = (ULONG)(((pool_size - ((ALIGN_TYPE)rounded_pool_start - (ALIGN_TYPE)pool_start)) / NX_PACKET_ALIGNMENT) * NX_PACKET_ALIGNMENT);
+
+    /* Calculate the address of payload. */
+    /*lint -e{923} suppress cast between ULONG and pointer.  */
+    payload_address = (CHAR *)((ALIGN_TYPE)rounded_pool_start + sizeof(NX_PACKET));
+
+    /* Align the address of payload. */
+    /*lint -e{923} suppress cast between ULONG and pointer.  */
+    payload_address = (CHAR *)((((ALIGN_TYPE)payload_address + NX_PACKET_ALIGNMENT  - 1) / NX_PACKET_ALIGNMENT) * NX_PACKET_ALIGNMENT);
+
+    /* Calculate the header size. */
+    /*lint -e{923} suppress cast between ULONG and pointer.  */
+    header_size = (ULONG)((ALIGN_TYPE)payload_address - (ALIGN_TYPE)rounded_pool_start);
+
+    /* Round the packet size up to something that helps guarantee proper alignment for header and payload.  */
+    rounded_payload_size =  (ULONG)(((header_size + payload_size + NX_PACKET_ALIGNMENT  - 1) / NX_PACKET_ALIGNMENT) * NX_PACKET_ALIGNMENT - header_size);
+
+    /* Check for an invalid pool and payload size.  */
+    if ((pool_size <= NX_PACKET_ALIGNMENT) || (!payload_size) ||
+        ((rounded_payload_size + header_size) > rounded_pool_size))
+    {
+        return(NX_SIZE_ERROR);
+    }
+
+    /* Calculate the end of the pool memory area.  */
+    end_memory =  ((CHAR *)pool_start) + (pool_size - 1);
+
+    /* Pickup current thread pointer.  */
+    current_thread =  tx_thread_identify();
+
+    /* Disable preemption temporarily.  */
+    if (current_thread)
+    {
+        tx_thread_preemption_change(current_thread, 0, &old_threshold);
+    }
+
+    /* Loop to check for the pool instance already created.  */
+    created_pool =   _nx_packet_pool_created_ptr;
+    created_count =  _nx_packet_pool_created_count;
+    while (created_count--)
+    {
+
+        /* Calculate the created pool's end of memory.  */
+        created_end =  created_pool -> nx_packet_pool_start + (created_pool -> nx_packet_pool_size - 1);
+
+        /* Is the new pool already created?  */
+        /*lint -e{946} suppress pointer subtraction, since it is necessary. */
+        if ((pool_ptr == created_pool) ||
+            ((pool_start >= (VOID *)created_pool -> nx_packet_pool_start) && (pool_start < (VOID *)created_end)) ||
+            ((end_memory  >= created_pool -> nx_packet_pool_start) && (end_memory  < created_end)))
+        {
+
+            /* Restore preemption.  */
+            if (current_thread)
+            {
+
+                /*lint -e{644} suppress variable might not be initialized, since "old_threshold" was initialized by previous tx_thread_preemption_change. */
+                tx_thread_preemption_change(current_thread, old_threshold, &old_threshold);
+            }
+
+            /* Duplicate packet pool created, return an error!  */
+            return(NX_PTR_ERROR);
+        }
+
+        /* Move to next entry.  */
+        created_pool =  created_pool -> nx_packet_pool_created_next;
+    }
+
+    /* Restore preemption.  */
+    if (current_thread)
+    {
+        tx_thread_preemption_change(current_thread, old_threshold, &old_threshold);
+    }
+
+    /* Check for appropriate caller.  */
+    NX_INIT_AND_THREADS_CALLER_CHECKING
+
+    /* Call actual packet pool create function.  */
+    status =  _nx_packet_pool_create(pool_ptr, name_ptr, payload_size, pool_start, pool_size);
+
+    /* Return completion status.  */
+    return(status);
+}
+
Index: ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/ports/cortex_m7/gnu/inc/nx_port.h
===================================================================
--- ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/ports/cortex_m7/gnu/inc/nx_port.h	(revision 69)
+++ ctrl/firmware/Main/CubeMX/Middlewares/ST/netxduo/ports/cortex_m7/gnu/inc/nx_port.h	(revision 69)
@@ -0,0 +1,196 @@
+/**************************************************************************/
+/*                                                                        */
+/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
+/*                                                                        */
+/*       This software is licensed under the Microsoft Software License   */
+/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
+/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
+/*       and in the root directory of this software.                      */
+/*                                                                        */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/**************************************************************************/
+/**                                                                       */ 
+/** NetX Component                                                        */
+/**                                                                       */
+/**   Port Specific                                                       */
+/**                                                                       */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/ 
+/*                                                                        */ 
+/*  PORT SPECIFIC C INFORMATION                            RELEASE        */ 
+/*                                                                        */ 
+/*    nx_port.h                                         Cortex-M7/GNU     */ 
+/*                                                           6.2.1        */
+/*                                                                        */
+/*  AUTHOR                                                                */
+/*                                                                        */
+/*    Yuxin Zhou, Microsoft Corporation                                   */
+/*                                                                        */
+/*  DESCRIPTION                                                           */ 
+/*                                                                        */ 
+/*    This file contains data type definitions that make the NetX         */ 
+/*    real-time TCP/IP function identically on a variety of different     */ 
+/*    processor architectures.                                            */ 
+/*                                                                        */ 
+/*  RELEASE HISTORY                                                       */ 
+/*                                                                        */ 
+/*    DATE              NAME                      DESCRIPTION             */
+/*                                                                        */
+/*  05-19-2020     Yuxin Zhou               Initial Version 6.0           */
+/*  09-30-2020     Yuxin Zhou               Modified comment(s),  and     */
+/*                                            corrected the code of       */
+/*                                            getting system state,       */
+/*                                            resulting in version 6.1    */
+/*  03-08-2023     Yajun Xia                Modified comment(s),          */
+/*                                            removed duplicated macros,  */
+/*                                            resulting in version 6.2.1  */
+/*                                                                        */
+/**************************************************************************/
+
+#ifndef NX_PORT_H
+#define NX_PORT_H
+
+/* Determine if the optional NetX user define file should be used.  */
+
+#ifdef NX_INCLUDE_USER_DEFINE_FILE
+
+
+/* Yes, include the user defines in nx_user.h. The defines in this file may 
+   alternately be defined on the command line.  */
+
+#include "nx_user.h"
+#endif
+
+
+/* Default to little endian, since this is what most ARM targets are.  */
+
+#define NX_LITTLE_ENDIAN    1
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+/* Define various constants for the port.  */ 
+
+#ifndef NX_IP_PERIODIC_RATE
+#define NX_IP_PERIODIC_RATE 100             /* Default IP periodic rate of 1 second for 
+                                               ports with 10ms timer interrupts.  This 
+                                               value may be defined instead at the 
+                                               command line and this value will not be
+                                               used.  */
+#endif
+
+
+/* Define macros that swap the endian for little endian ports.  */
+#ifdef NX_LITTLE_ENDIAN
+#define NX_CHANGE_ULONG_ENDIAN(arg)       (arg) = __builtin_bswap32(arg)
+#define NX_CHANGE_USHORT_ENDIAN(arg)      (arg) = __builtin_bswap16(arg)
+
+
+#ifndef htonl
+#define htonl(val)  __builtin_bswap32(val)
+#endif /* htonl */
+#ifndef ntohl
+#define ntohl(val)  __builtin_bswap32(val)
+#endif /* htonl */
+
+#ifndef htons
+#define htons(val)  __builtin_bswap16(val)
+#endif /*htons */
+
+#ifndef ntohs
+#define ntohs(val)  __builtin_bswap16(val)
+#endif /*htons */
+
+
+#else
+#define NX_CHANGE_ULONG_ENDIAN(a)
+#define NX_CHANGE_USHORT_ENDIAN(a)
+
+#ifndef htons
+#define htons(val) (val)
+#endif /* htons */
+
+#ifndef ntohs
+#define ntohs(val) (val)
+#endif /* ntohs */
+
+#ifndef ntohl
+#define ntohl(val) (val)
+#endif
+
+#ifndef htonl
+#define htonl(val) (val)
+#endif /* htonl */
+#endif
+
+
+/* Define several macros for the error checking shell in NetX.  */
+
+#ifndef TX_TIMER_PROCESS_IN_ISR
+
+#define NX_CALLER_CHECKING_EXTERNS          extern  TX_THREAD           *_tx_thread_current_ptr; \
+                                            extern  TX_THREAD           _tx_timer_thread; \
+                                            extern  volatile ULONG      _tx_thread_system_state;
+
+#define NX_THREADS_ONLY_CALLER_CHECKING     if ((TX_THREAD_GET_SYSTEM_STATE()) || \
+                                                (_tx_thread_current_ptr == TX_NULL) || \
+                                                (_tx_thread_current_ptr == &_tx_timer_thread)) \
+                                                return(NX_CALLER_ERROR);
+
+#define NX_INIT_AND_THREADS_CALLER_CHECKING if (((TX_THREAD_GET_SYSTEM_STATE()) && (TX_THREAD_GET_SYSTEM_STATE() < ((ULONG) 0xF0F0F0F0))) || \
+                                                (_tx_thread_current_ptr == &_tx_timer_thread)) \
+                                                return(NX_CALLER_ERROR);
+
+
+#define NX_NOT_ISR_CALLER_CHECKING          if ((TX_THREAD_GET_SYSTEM_STATE()) && (TX_THREAD_GET_SYSTEM_STATE() < ((ULONG) 0xF0F0F0F0))) \
+                                                return(NX_CALLER_ERROR);
+
+#define NX_THREAD_WAIT_CALLER_CHECKING      if ((wait_option) && \
+                                               ((_tx_thread_current_ptr == NX_NULL) || (TX_THREAD_GET_SYSTEM_STATE()) || (_tx_thread_current_ptr == &_tx_timer_thread))) \
+                                            return(NX_CALLER_ERROR);
+
+
+#else
+
+
+
+#define NX_CALLER_CHECKING_EXTERNS          extern  TX_THREAD           *_tx_thread_current_ptr; \
+                                            extern  volatile ULONG      _tx_thread_system_state;
+
+#define NX_THREADS_ONLY_CALLER_CHECKING     if ((TX_THREAD_GET_SYSTEM_STATE()) || \
+                                                (_tx_thread_current_ptr == TX_NULL)) \
+                                                return(NX_CALLER_ERROR);
+
+#define NX_INIT_AND_THREADS_CALLER_CHECKING if (((TX_THREAD_GET_SYSTEM_STATE()) && (TX_THREAD_GET_SYSTEM_STATE() < ((ULONG) 0xF0F0F0F0)))) \
+                                                return(NX_CALLER_ERROR);
+
+#define NX_NOT_ISR_CALLER_CHECKING          if ((TX_THREAD_GET_SYSTEM_STATE()) && (TX_THREAD_GET_SYSTEM_STATE() < ((ULONG) 0xF0F0F0F0))) \
+                                                return(NX_CALLER_ERROR);
+
+#define NX_THREAD_WAIT_CALLER_CHECKING      if ((wait_option) && \
+                                               ((_tx_thread_current_ptr == NX_NULL) || (TX_THREAD_GET_SYSTEM_STATE()))) \
+                                            return(NX_CALLER_ERROR);
+
+#endif
+
+
+/* Define the version ID of NetX.  This may be utilized by the application.  */
+
+#ifdef NX_SYSTEM_INIT
+CHAR                            _nx_version_id[] = 
+                                    "Copyright (c) Microsoft Corporation. All rights reserved.  *  NetX Duo Cortex-M7/GNU Version 6.4.0 *";
+#else
+extern  CHAR                    _nx_version_id[];
+#endif
+
+#endif
+
