AzureMXChip/MXCHIPAZ3166/core/lib/netxduo/common/src/nx_icmpv6_process_packet_too_big.c
UINT _nx_icmpv6_process_packet_too_big(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{

UINT                       status = NX_INVALID_MTU_DATA;
NX_ICMPV6_OPTION_MTU      *icmpv6_mtu_option_ptr;
ULONG                      mtu;
NX_IPV6_DESTINATION_ENTRY *dest_entry_ptr;
ULONG                     *original_destination_ip;
ULONG                      default_next_hop_address[4];
NX_IPV6_HEADER            *ip_header_ptr, *original_ip_header_ptr;
NX_INTERFACE              *if_ptr;

    /* Add debug information. */
    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);

#ifndef NX_DISABLE_RX_SIZE_CHECKING
    if (packet_ptr -> nx_packet_length < sizeof(NX_ICMPV6_OPTION_MTU))
    {
#ifndef NX_DISABLE_ICMP_INFO

        /* Increment the ICMP invalid message count.  */
        ip_ptr -> nx_ip_icmp_invalid_packets++;
#endif

        /* Invalid ICMP message, just release it.  */
        _nx_packet_release(packet_ptr);
        return(NX_NOT_SUCCESSFUL);
    }
#endif /* NX_DISABLE_RX_SIZE_CHECKING */

    memset(&default_next_hop_address[0], 0, (4 * sizeof(ULONG)));

    if_ptr = packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached;

    /* Set a local pointer to the ICMPv6 Option data. */
    /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */
    icmpv6_mtu_option_ptr = (NX_ICMPV6_OPTION_MTU *)packet_ptr -> nx_packet_prepend_ptr;

    /* Parse the original sender data. */
    /*lint -e{929} -e{826} -e{740} suppress cast of pointer to pointer, since it is necessary  */
    original_ip_header_ptr = (NX_IPV6_HEADER *)(&(icmpv6_mtu_option_ptr ->  nx_icmpv6_option_mtu_message));

    /* Extract the original sender from the IP header. */
    packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV6_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_ip_header;


    /* Yes this looks like a valid IP header for the original offending packet. */
    original_destination_ip = original_ip_header_ptr -> nx_ip_header_destination_ip;
    NX_IPV6_ADDRESS_CHANGE_ENDIAN(original_destination_ip);
    COPY_IPV6_ADDRESS(ip_header_ptr -> nx_ip_header_source_ip, &default_next_hop_address[0]);

    /*  Handle endianness. */
    NX_CHANGE_ULONG_ENDIAN(icmpv6_mtu_option_ptr -> nx_icmpv6_option_mtu_path_mtu);

    /* Create a local variable for convenience. */
    mtu = icmpv6_mtu_option_ptr -> nx_icmpv6_option_mtu_path_mtu;

    /* MTU data is valid if it is non zero, and is no more than the driver MTU. */
    if ((mtu > 0) && (mtu <= if_ptr -> nx_interface_ip_mtu_size))
    {

        /* Add destination table. */
        status = _nx_icmpv6_dest_table_add(ip_ptr, original_destination_ip,
                                           &dest_entry_ptr, &default_next_hop_address[0], mtu, 0,
                                           packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr);
    }

    /* Release the packet. */
    _nx_packet_release(packet_ptr);

    /* Return the completion code. */
    return(status);
}
/**************************************************************************/
/*                                                                        */
/*  FUNCTION                                               RELEASE        */
/*                                                                        */
/*    _nx_icmpv6_process_packet_too_big                   PORTABLE C      */
/*                                                           6.1          */
/*  AUTHOR                                                                */
/*                                                                        */
/*    Yuxin Zhou, Microsoft Corporation                                   */
/*                                                                        */
/*  DESCRIPTION                                                           */
/*                                                                        */
/*    This function handles an ICMPv6 error message indicating the next   */
/*    hop or beyond has a smaller MTU that the packet payload.  It sets   */
/*    the IP task MTU to the next hop MTU in the option header.           */
/*                                                                        */
/*    This function is called from IP thread periodic process routine.    */
/*    It starts the minimum Path MTU Discovery process if the interface   */
/*    address after the IP instance is initialized and its MTU established*/
/*    by the Ethernet driver.                                             */
/*                                                                        */
/*  INPUT                                                                 */
/*                                                                        */
/*    ip_ptr                                Pointer to IP instance        */
/*    packet_ptr                            Pointer to Packet Too Big     */
/*                                            ICMPv6 packet received      */
/*                                                                        */
/*  OUTPUT                                                                */
/*                                                                        */
/*    NX_SUCCESS                            Successful completion         */
/*                                                                        */
/*  CALLS                                                                 */
/*                                                                        */
/*     _nx_icmpv6_dest_table_find         Find destination in table and   */
/*                                             update path MTU in table   */
/*    memset                              Set the memory                  */
/*                                                                        */
/*  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    */
/*                                                                        */
/**************************************************************************/
FUNCTION                                               RELEASE

_nx_icmpv6_process_packet_too_big                   PORTABLE C
6.1
AUTHOR

Yuxin Zhou, Microsoft Corporation

DESCRIPTION

This function handles an ICMPv6 error message indicating the next
hop or beyond has a smaller MTU that the packet payload.  It sets
the IP task MTU to the next hop MTU in the option header.

This function is called from IP thread periodic process routine.
It starts the minimum Path MTU Discovery process if the interface
address after the IP instance is initialized and its MTU established
by the Ethernet driver.

INPUT

ip_ptr                                Pointer to IP instance
packet_ptr                            Pointer to Packet Too Big
ICMPv6 packet received

OUTPUT



CALLS

_nx_icmpv6_dest_table_find         Find destination in table and
update path MTU in table
memset                              Set the memory

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
FUNCTION RELEASE _nx_icmpv6_process_packet_too_big PORTABLE C 6 . 1 AUTHOR Yuxin Zhou Microsoft Corporation DESCRIPTION This function handles an ICMPv6 error message indicating the next hop or beyond has a smaller MTU that the packet payload . It sets the IP task MTU to the next hop MTU in the option header . This function is called from IP thread periodic process routine . It starts the minimum Path MTU Discovery process if the interface address after the IP instance is initialized and its MTU established by the Ethernet driver . INPUT ip_ptr Pointer to IP instance packet_ptr Pointer to Packet Too Big ICMPv6 packet received OUTPUT CALLS _nx_icmpv6_dest_table_find Find destination in table and update path MTU in table memset Set the memory 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_process_packet_too_big(NX_IP *ip_ptr, NX_PACKET *packet_ptr)
{
UINT                       status = NX_INVALID_MTU_DATA;
NX_ICMPV6_OPTION_MTU      *icmpv6_mtu_option_ptr;
ULONG                      mtu;
NX_IPV6_DESTINATION_ENTRY *dest_entry_ptr;
ULONG                     *original_destination_ip;
ULONG                      default_next_hop_address[4];
NX_IPV6_HEADER            *ip_header_ptr, *original_ip_header_ptr;
NX_INTERFACE              *if_ptr;
    NX_PACKET_DEBUG(__FILE__, __LINE__, packet_ptr);
#ifndef NX_DISABLE_RX_SIZE_CHECKING
    if (packet_ptr -> nx_packet_length < sizeof(NX_ICMPV6_OPTION_MTU))
    {
#ifndef NX_DISABLE_ICMP_INFO
        ip_ptr -> nx_ip_icmp_invalid_packets++;
#endif
        _nx_packet_release(packet_ptr);
        return(NX_NOT_SUCCESSFUL);
    }
#endif 
    memset(&default_next_hop_address[0], 0, (4 * sizeof(ULONG)));
    if_ptr = packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached;
    icmpv6_mtu_option_ptr = (NX_ICMPV6_OPTION_MTU *)packet_ptr -> nx_packet_prepend_ptr;
    original_ip_header_ptr = (NX_IPV6_HEADER *)(&(icmpv6_mtu_option_ptr ->  nx_icmpv6_option_mtu_message));
    packet_ptr -> nx_packet_prepend_ptr -= sizeof(NX_IPV6_HEADER);
    ip_header_ptr = (NX_IPV6_HEADER *)packet_ptr -> nx_packet_ip_header;
    original_destination_ip = original_ip_header_ptr -> nx_ip_header_destination_ip;
    NX_IPV6_ADDRESS_CHANGE_ENDIAN(original_destination_ip);
    COPY_IPV6_ADDRESS(ip_header_ptr -> nx_ip_header_source_ip, &default_next_hop_address[0]);
    NX_CHANGE_ULONG_ENDIAN(icmpv6_mtu_option_ptr -> nx_icmpv6_option_mtu_path_mtu);
    mtu = icmpv6_mtu_option_ptr -> nx_icmpv6_option_mtu_path_mtu;
    if ((mtu > 0) && (mtu <= if_ptr -> nx_interface_ip_mtu_size))
    {
        status = _nx_icmpv6_dest_table_add(ip_ptr, original_destination_ip,
                                           &dest_entry_ptr, &default_next_hop_address[0], mtu, 0,
                                           packet_ptr -> nx_packet_address.nx_packet_ipv6_address_ptr);
    }
    _nx_packet_release(packet_ptr);
    return(status);
}
UINT _nx_icmpv6_process_packet_too_big ( NX_IP * ip_ptr , NX_PACKET * packet_ptr ) { UINT status = NX_INVALID_MTU_DATA ; NX_ICMPV6_OPTION_MTU * icmpv6_mtu_option_ptr ; ULONG mtu ; NX_IPV6_DESTINATION_ENTRY * dest_entry_ptr ; ULONG * original_destination_ip ; ULONG default_next_hop_address [ 4 ] ; NX_IPV6_HEADER * ip_header_ptr , * original_ip_header_ptr ; NX_INTERFACE * if_ptr ; NX_PACKET_DEBUG ( __FILE__ , __LINE__ , packet_ptr ) ; #ifndef NX_DISABLE_RX_SIZE_CHECKING if ( packet_ptr -> nx_packet_length < sizeof ( NX_ICMPV6_OPTION_MTU ) ) { #ifndef NX_DISABLE_ICMP_INFO ip_ptr -> nx_ip_icmp_invalid_packets ++ ; #endif _nx_packet_release ( packet_ptr ) ; return ( NX_NOT_SUCCESSFUL ) ; } #endif memset ( & default_next_hop_address [ 0 ] , 0 , ( 4 * sizeof ( ULONG ) ) ) ; if_ptr = packet_ptr -> nx_packet_address . nx_packet_ipv6_address_ptr -> nxd_ipv6_address_attached ; icmpv6_mtu_option_ptr = ( NX_ICMPV6_OPTION_MTU * ) packet_ptr -> nx_packet_prepend_ptr ; original_ip_header_ptr = ( NX_IPV6_HEADER * ) ( & ( icmpv6_mtu_option_ptr -> nx_icmpv6_option_mtu_message ) ) ; packet_ptr -> nx_packet_prepend_ptr -= sizeof ( NX_IPV6_HEADER ) ; ip_header_ptr = ( NX_IPV6_HEADER * ) packet_ptr -> nx_packet_ip_header ; original_destination_ip = original_ip_header_ptr -> nx_ip_header_destination_ip ; NX_IPV6_ADDRESS_CHANGE_ENDIAN ( original_destination_ip ) ; COPY_IPV6_ADDRESS ( ip_header_ptr -> nx_ip_header_source_ip , & default_next_hop_address [ 0 ] ) ; NX_CHANGE_ULONG_ENDIAN ( icmpv6_mtu_option_ptr -> nx_icmpv6_option_mtu_path_mtu ) ; mtu = icmpv6_mtu_option_ptr -> nx_icmpv6_option_mtu_path_mtu ; if ( ( mtu > 0 ) && ( mtu <= if_ptr -> nx_interface_ip_mtu_size ) ) { status = _nx_icmpv6_dest_table_add ( ip_ptr , original_destination_ip , & dest_entry_ptr , & default_next_hop_address [ 0 ] , mtu , 0 , packet_ptr -> nx_packet_address . nx_packet_ipv6_address_ptr ) ; } _nx_packet_release ( packet_ptr ) ; return ( status ) ; }
FUNCTION                                               RELEASE
FUNCTION RELEASE
/* Add debug information. */ /* Increment the ICMP invalid message count.  */ /* Invalid ICMP message, just release it.  */ /* NX_DISABLE_RX_SIZE_CHECKING */ /* Set a local pointer to the ICMPv6 Option data. */ /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */ /* Parse the original sender data. */ /*lint -e{929} -e{826} -e{740} suppress cast of pointer to pointer, since it is necessary  */ /* Extract the original sender from the IP header. */ /*lint -e{927} -e{826} suppress cast of pointer to pointer, since it is necessary  */ /* Yes this looks like a valid IP header for the original offending packet. */ /*  Handle endianness. */ /* Create a local variable for convenience. */ /* MTU data is valid if it is non zero, and is no more than the driver MTU. */ /* Add destination table. */ /* Release the packet. */ /* Return the completion code. */