Help Center> Virtual Private Cloud> User Guide> Appendix> Configuring the NAT64 TOA Plug-in

Configuring the NAT64 TOA Plug-in

Scenarios

If an IPv6 address is used for communication, the IPv6 address of the visitor needs to be obtained. The TOA kernel module installed on backend servers is used to obtain the IPv6 IP address before NAT64 translation.

This section describes how to compile the NAT64 TOA kernel module in the OS. This configuration is only available in CN North-Beijing4.

  • TOA does not support UDP.
  • The TOA module can work properly in the following OSs and the methods for installing other kernel versions are similar:
    • CentOS 7/7.2 (Kernel version 3.10.0)
    • Ubuntu 14.04.3(Kernel version 3.12.0)
    • Ubuntu 16.04.3 (Kernel version 4.4.0)

Prerequisites

  • The development environment for compiling the kernel module must be the same as that of the current kernel.
  • VMs can access the OS repositories.
  • Users other than root must have sudo permissions.

Procedure

TOA module compilation and loading

In the following operations, the Linux kernel version is 3.0 or later.

  1. Prepare the compilation environment.

    During the installation, you need to download the required kernel module development package from the Internet if it cannot be found in the source.

    The following are operations for compiling the kernel module in different Linux OSs. Choose appropriate operations as needed.

    • CentOS
      1. Run the following command to install the GCC:

        sudo yum install gcc

      2. Run the following command to install the make tool:

        sudo yum install make

      3. Run the following command to install the kernel module development package (the versions of the development package header and module library must be the same as that of the kernel):

        sudo yum install kernel-devel-`uname -r`

        During the installation, you can visit the following address for downloading the required kernel module development package if it cannot be found in the source:

        https://mirror.netcologne.de/oracle-linux-repos/ol7_latest/getPackage/

        For example, run the following command to install 3.10.0-693.11.1.el7.x86_64:

        rpm -ivh kernel-devel-3.10.0-693.11.1.el7.x86_64.rpm

    • Ubuntu and Debian
      1. Run the following command to install the GCC:

        sudo apt-get install gcc

      1. Run the following command to install the make tool:

        sudo apt-get install make

      1. Run the following command to install the kernel module development package (the versions of the development package header and module library must be the same as that of the kernel):

        sudo apt-get install linux-headers-`uname -r`

    • SUSE
      1. Run the following command to install the GCC:

        sudo zypper install gcc

      2. Run the following command to install the make tool:

        sudo zypper install make

      3. Run the following command to install the kernel module development package (the versions of the development package header and module library must be the same as that of the kernel):

        sudo zypper install enel-default-devel

    • CoreOS

      For CoreOS, the kernel module is to be compiled in a container, which must be started before the kernel module is compiled.

      For detailed operations, see the CoreOS documentation. Visit the following address and obtain the documentation:

      https://coreos.com/os/docs/latest/kernel-modules.html

  2. Compile the Kernel module.
    1. Use the git tool and run the following command to download the TOA kernel module source code:

      git clone https://github.com/huaweicloud/elb-toa

      git checkout IPv6

      If the git tool is not installed, visit the following address and download the TOA kernel module source code:

      https://github.com/huaweicloud/elb-toa/tree/IPv6

    2. Run the following commands to enter the source code directory and compile the module:

      cd src

      make

      If no warning or error information is prompted, the compilation is successful. Verify that the toa.ko file has generated in the current directory.

  3. Load the Kernel module.
    1. Run the following command to load the kernel module:

      sudo insmod toa.ko

    2. Run the following command to check the module loading and to view the kernel output information:

      dmesg | grep TOA

      If TOA: toa loaded is displayed in the command output, the kernel module has loaded.

      After compiling the CoreOS kernel module in the container, copy the kernel module to the host system and then load it in the host system. Because the container for compiling the kernel module shares the /lib/modules directory with the host system, you can copy the kernel module in the container to this directory so that the host system can use it.

  4. Set the script to enable it to automatically load the kernel module.

    To make the TOA kernel module take effect upon system start, you can add the command for loading the TOA kernel module to your startup script.

    You can use either of the following methods to automatically load the kernel module:

    • Add the command for loading the TOA kernel module to the customized startup script as required.
    • Perform the following operations to configure the startup script:
      1. Create the toa.modules file in the /etc/sysconfig/modules/ directory. This file contains the TOA kernel module loading script.

        The following is an example of the content in the toa.modules file.

        #!/bin/sh

        /sbin/modinfo -F filename /root/toa/toa.ko > /dev/null 2>&1

        if [ $? -eq 0 ]; then

        /sbin/insmod /root/toa/toa.ko

        fi

        /root/toa/toa.ko is the path of the TOA kernel module file. You need to replace it with their actual path.

      2. Run the following command to add execution permissions for the toa.modules startup script:

        sudo chmod +x /etc/sysconfig/modules/toa.modules

        After the kernel is upgraded, the current TOA kernel module does not match. Therefore, you need to compile the TOA kernel module again.

  5. Install the kernel module on multiple nodes.

    To load the kernel module in the same OSs, copy the toa.ko file to VMs where the kernel module is to be loaded and then perform the operations in 3.

    After the kernel module is successfully loaded, applications can obtain the IPv6 address contained in the request.

    The OS version of the node must be the same as that of the kernel.

Backend server adaption

To use the NAT64 TOA function for transparent source address transmission, the source code of the back-end server application needs to be adapted as follows (the following uses the C programming language as an example):

  1. Define a data structure for storing addresses.

    struct toa_nat64_peer uaddr

  2. Call the function to obtain the IPv6 address.

    getsockopt(connfd, IPPROTO_IP, TOA_SO_GET_LOOKUP, &uaddr, &len)

    Where

    connfd: socket fd that provides service connection on the server

    IPPROTO_IP: Fixed

    len: sizeof(struct toa_nat64_peer)

    TOA_SO_GET_LOOKUP: Constant value 4096

    uaddr: Used to store NAT64 TOA.

  3. Output the address and save it.

    uaddr.saddr

  4. The following is a code example:
    //Define the data structure and variable for storing the NAT64 TOA information.
    enum {
        TOA_BASE_CTL            = 4096,
        TOA_SO_SET_MAX          = TOA_BASE_CTL,
        TOA_SO_GET_LOOKUP       = TOA_BASE_CTL,
        TOA_SO_GET_MAX          = TOA_SO_GET_LOOKUP,
    };
     
    struct toa_nat64_peer {
        struct in6_addr saddr;
        uint16_t sport;
    };
    struct toa_nat64_peer uaddr;
    ......
    //Obtain the socket of the server.
    sockaddr.sin_family = AF_INET;
    sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    sockaddr.sin_port = htons(PORT);
    listenfd = socket(AF_INET,SOCK_STREAM,0);
    bind(listenfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr))
    ......
    //Listen to the corresponding socket.
    connfd = accept(listenfd, (struct sockaddr*)&caddr, &length);
     
    //Obtain the information about the corresponding NAT64 TOA.
    char from[40];
    int len = sizeof(struct toa_nat64_peer);
    if (getsockopt(connfd, IPPROTO_IP, TOA_SO_GET_LOOKUP, &uaddr, &len) == 0) {
    inet_ntop(AF_INET6, &uaddr.saddr, from, sizeof(from));
    //Obtain the source IP address and port number.
    printf("real client [%s]:%d\n", from, ntohs(uaddr.sport));
    }