Help Center/ Virtual Private Cloud/ User Guide/ Elastic Network Interface and Supplementary Network Interface/ Network Interface Configuration Examples/ Configuring Policy-based Routes for an ECS with Multiple Network Interfaces/ Automatically Configuring IPv4 and IPv6 Policy-based Routes for a Linux ECS with Multiple Network Interfaces (Huawei Cloud EulerOS 2.0/CentOS 8.0 or Later)
Updated on 2025-07-14 GMT+08:00

Automatically Configuring IPv4 and IPv6 Policy-based Routes for a Linux ECS with Multiple Network Interfaces (Huawei Cloud EulerOS 2.0/CentOS 8.0 or Later)

Scenarios

This section describes how to use an automation script to configure policy-based routes for a Linux ECS with two network interfaces. The automation script supports Huawei Cloud EulerOS 2.0, CentOS 8.0 and later versions.

For details about the background knowledge and networking of an ECS with two network interfaces, see Overview.

Configuring Policy-based Routes for a Linux ECS with IPv4 Addresses

  1. Collect the information, such as IPv4 addresses, about ECS network interfaces for configuring policy-based routes.

    For details, see Collecting ECS Network Information.

    In this example, the network information of the ECS is shown in Table 1.

    Table 1 Linux ECSs using IPv4 addresses

    Type

    Primary Network Interface

    Extended Network Interface

    Source

    • IPv4 address: 10.0.0.115
    • Subnet IPv4 CIDR block: 10.0.0.0/24
    • Subnet IPv4 gateway: 10.0.0.1
    • IPv4 address: 10.0.1.183
    • Subnet IPv4 CIDR block: 10.0.1.0/24
    • Subnet IPv4 gateway: 10.0.1.1

    Destination

    IPv4 address: 10.0.2.12

    N/A

  2. Log in to the source ECS.

    For details, see How Do I Log In to My ECS?

  3. Check whether the source ECS can use its primary network interface to communicate with the destination ECS using IPv4 addresses:

    Before configuring policy-based routes, ensure that the source ECS can use its primary network interface to communicate with the destination ECS.

    ping -I <IPv4-address-of-the-primary-network-interface-on-the-source-ECS> <IPv4-address-of-the-network-interface-on-the-destination-ECS>

    Example command:

    ping -I 10.0.0.115 10.0.2.12

    If information similar to the following is displayed, the source ECS can use its primary network interface to communicate with the destination ECS.
    [root@ecs-resource ~]# ping -I 10.0.0.115 10.0.2.12
    PING 10.0.2.12 (10.0.2.12) from 10.0.0.115 : 56(84) bytes of data.
    64 bytes from 10.0.2.12: icmp_seq=1 ttl=64 time=0.775 ms
    64 bytes from 10.0.2.12: icmp_seq=2 ttl=64 time=0.268 ms
    64 bytes from 10.0.2.12: icmp_seq=3 ttl=64 time=0.220 ms
    64 bytes from 10.0.2.12: icmp_seq=4 ttl=64 time=0.167 ms
    ^C
    --- 10.0.2.12 ping statistics ---
  4. Query the network interface names of the source ECS:

    ifconfig

    Search for the network interface names based on IP addresses.
    • The IPv4 address of the primary network interface is 10.0.0.115, and its name is eth0.
    • The IPv4 address of the extended network interface is 10.0.1.183, and its name is eth1.
    [root@ecs-resource ~]# ifconfig
    eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 10.0.0.115  netmask 255.255.255.0  broadcast 10.0.0.255
            inet6 fe80::f816:3eff:fe92:6e0e  prefixlen 64  scopeid 0x20<link>
            ether fa:16:3e:92:6e:0e  txqueuelen 1000  (Ethernet)
            RX packets 432288  bytes 135762012 (129.4 MiB)
            RX errors 0  dropped 0  overruns 0  frame 1655
            TX packets 423744  bytes 106716932 (101.7 MiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 10.0.1.183  netmask 255.255.255.0  broadcast 10.0.1.255
            inet6 fe80::f816:3eff:febf:5818  prefixlen 64  scopeid 0x20<link>
            ether fa:16:3e:bf:58:18  txqueuelen 1000  (Ethernet)
            RX packets 9028  bytes 536972 (524.3 KiB)
            RX errors 0  dropped 0  overruns 0  frame 1915
            TX packets 6290  bytes 272473 (266.0 KiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
  5. Create an automation script to configure IPv4 routes:
    1. Create the automation configuration script file 15-policy-route.sh:

      vi /etc/NetworkManager/dispatcher.d/15-policy-route.sh

    2. Press i to enter the editing mode.
    3. Add the automation script to the file.
      #!/bin/bash
      
      if [ "$2" != "up" ]; then
          exit 0
      fi
      
      interface=$1
      
      check_route_table() {
          local route_table_id=$1
          local ip_version=$2
          local max_attempts=100
          local attempts=0
      
          while [ $attempts -lt $max_attempts ]; do
              output=$(ip -$ip_version route show table $route_table_id &>/dev/null)
              if [ $? -ne 0 ] || [ -z "$output" ]; then
                  break
              else
                  route_table_id=$((route_table_id + 1))
                  attempts=$((attempts + 1))
              fi
          done
      
          echo $route_table_id
      }
      
      add_ipv4_route_table() {
          local DEFAULT_IPV4_ROUTE_TABLE_ID=1000
          v4_route_table_id=$(ip route show table all | grep -F "default via $gateway dev $interface table" | awk '{print $NF}')
          if [ -z $v4_route_table_id ]; then
              interface_number=$(echo $interface | grep -o '[0-9]*$')
              if [ -z "$interface_number" ]; then
                  v4_route_table_id="$DEFAULT_IPV4_ROUTE_TABLE_ID"
              else
                  v4_route_table_id=$((DEFAULT_IPV4_ROUTE_TABLE_ID + interface_number))
              fi
      
              v4_route_table_id=$(check_route_table $v4_route_table_id 4)
      
              echo "add policy route for dev: $interface table: $v4_route_table_id subnet: $subnet gateway: $gateway"
      
              ip route add default via $gateway dev $interface table $v4_route_table_id
              ip route add $subnet dev $interface table $v4_route_table_id
          fi
      }
      
      generate_ipv4_policy_route() {
          subnet=$(nmcli device show $interface | grep -F 'IP4.ROUTE' | grep -F 'nh = 0.0.0.0' | cut -d'=' -f2 | cut -d',' -f1 | tr -d ' ' | head -n 1)
          gateway=$(ipcalc -i $subnet | awk '/HostMin/ {print $2}')
      
          add_ipv4_route_table
      
          nmcli device show $interface | grep -F 'IP4.ADDRESS' | while read -r line; do
              IP=$(echo $line | awk '{print $2}' | cut -d'/' -f1)
              if ip rule list | grep -F "$v4_route_table_id" | grep -q "$IP"; then
                  echo "ip rule already exists for $IP with table $v4_route_table_id"
                  continue
              fi
      
              echo "Adding rule for $IP on $interface with table $v4_route_table_id"
              ip rule add from $IP table $v4_route_table_id
          done
      }
      
      generate_ipv4_policy_route
    4. Press ESC to exit and enter :wq! to save the configuration.
    5. Check the permissions on the automatic configuration script file 15-policy-route.sh:

      ll /etc/NetworkManager/dispatcher.d/

      Information similar to the following is displayed. The permission on 15-policy-route.sh is -rw-r--r--, which is different from that on other system files, for example, permission -rwxr-xr-x on the file 10-ifcfg-rh-routes.sh.
      [root@ecs-resource ~]# ll /etc/NetworkManager/dispatcher.d/
      total 36
      -rwxr-xr-x. 1 root root 3840 Feb 26 17:45 10-ifcfg-rh-routes.sh
      -rwxr-xr-x. 1 root root 1062 Feb 26 17:45 11-dhclient
      -rw-r--r--  1 root root 2019 Jun 18 12:21 15-policy-route.sh
      -rwxr-xr-x. 1 root root 1412 Feb 26 17:45 20-chrony-dhcp
      -rwxr-xr-x. 1 root root  455 Feb 26 17:45 20-chrony-onoffline
      -rwxrwxr-x  1 root root  719 May 10  2019 hook-network-manager
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 no-wait.d
      drwxr-xr-x. 2 root root 4096 Feb 26 17:45 pre-down.d
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 pre-up.d
    6. Grant permissions on the automation configuration script file 15-policy-route.sh:

      sudo chown root:root /etc/NetworkManager/dispatcher.d/15-policy-route.sh

      sudo chmod 755 /etc/NetworkManager/dispatcher.d/15-policy-route.sh

    7. Check the permissions on the automatic configuration script file 15-policy-route.sh again:

      ll /etc/NetworkManager/dispatcher.d/

      Information similar to the following is displayed. The permission on 15-policy-route.sh is -rwxr-xr-x.
      [root@ecs-resource ~]# ll /etc/NetworkManager/dispatcher.d/
      total 36
      -rwxr-xr-x. 1 root root 3840 Feb 26 17:45 10-ifcfg-rh-routes.sh
      -rwxr-xr-x. 1 root root 1062 Feb 26 17:45 11-dhclient
      -rwxr-xr-x  1 root root 2019 Jun 18 12:21 15-policy-route.sh
      -rwxr-xr-x. 1 root root 1412 Feb 26 17:45 20-chrony-dhcp
      -rwxr-xr-x. 1 root root  455 Feb 26 17:45 20-chrony-onoffline
      -rwxrwxr-x  1 root root  719 May 10  2019 hook-network-manager
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 no-wait.d
      drwxr-xr-x. 2 root root 4096 Feb 26 17:45 pre-down.d
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 pre-up.d
    8. Restart the network service to execute the 15-policy-route.sh script:

      systemctl restart NetworkManager

      Before restarting the network service, ensure that services are not affected.

  6. Check whether the policy-based routes are added for the network interfaces with IPv4 addresses.

    ip rule

    ip route show table 1000

    ip route show table 1001

    table 1000 is the route table name of the primary network interface, and table 1001 is the route table name of the extended network interface.

    If information similar to the following is displayed, the policy-based routes have been added for the network interfaces with IPv4 addresses.
    [root@ecs-resource ~]# ip rule
    0:      from all lookup local
    32764:  from 10.0.1.183 lookup 1001
    32765:  from 10.0.0.115 lookup 1000
    32766:  from all lookup main
    32767:  from all lookup default
    [root@ecs-resource ~]# ip route show table 1000
    default via 10.0.0.1 dev eth0 
    10.0.0.0/24 dev eth0 scope link 
    [root@ecs-resource ~]# ip route show table 1001
    default via 10.0.1.1 dev eth1 
    10.0.1.0/24 dev eth1 scope link 
  7. Check whether the source and destination ECSs can communicate with each other using IPv4 addresses.

    ping -I <IPv4-address-of-the-primary-network-interface-on-the-source-ECS> <IPv4-address-of-the-network-interface-on-the-destination-ECS>

    ping -I <IPv4-address-of-the-extended-network-interface-on-the-source-ECS> <IPv4-address-of-the-network-interface-on-the-destination-ECS>

    Example commands:

    ping -I 10.0.0.115 10.0.2.12

    ping -I 10.0.1.183 10.0.2.12

    If information similar to the following is displayed, both the IPv4 addresses of the source ECS can communicate with the destination ECS, indicating that the IPv4 policy-based routes are successfully configured.
    [root@ecs-resource ~]# ping -I 10.0.0.115 10.0.2.12
    PING 10.0.2.12 (10.0.2.12) from 10.0.0.115 : 56(84) bytes of data.
    64 bytes from 10.0.2.12: icmp_seq=1 ttl=64 time=0.231 ms
    64 bytes from 10.0.2.12: icmp_seq=2 ttl=64 time=0.195 ms
    ^C
    --- 10.0.2.12 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1043ms
    rtt min/avg/max/mdev = 0.195/0.213/0.231/0.018 ms
    [root@ecs-resource ~]# ping -I 10.0.1.183 10.0.2.12
    PING 10.0.2.12 (10.0.2.12) from 10.0.1.183 : 56(84) bytes of data.
    64 bytes from 10.0.2.12: icmp_seq=1 ttl=64 time=0.274 ms
    64 bytes from 10.0.2.12: icmp_seq=2 ttl=64 time=0.196 ms
    64 bytes from 10.0.2.12: icmp_seq=3 ttl=64 time=0.125 ms
    ^C
    --- 10.0.2.12 ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2042ms
    rtt min/avg/max/mdev = 0.125/0.198/0.274/0.060 ms

Configuring Policy-based Routes for a Linux ECS with IPv6 Addresses

  1. Collect the information, such as IPv4 and IPv6 addresses, about ECS network interfaces for configuring policy-based routes.

    For details, see Collecting ECS Network Information.

    In this example, the network information of the ECS is shown in Table 2.

    Table 2 Linux ECSs using IPv4 and IPv6 addresses

    Type

    Primary Network Interface

    Extended Network Interface

    Source

    • IPv4 address: 10.0.0.133
    • IPv6 address: 2407:c080:802:1f85:918b:9039:41b2:24a8
    • Subnet IPv6 CIDR block: 2407:c080:802:1f85::/64
    • Subnet IPv6 gateway: 2407:c080:802:1f85::1
    • IPv4 address: 10.0.1.120
    • IPv6 address: 2407:c080:802:2107:ab85:4a27:d20:2119
    • Subnet IPv6 CIDR block: 2407:c080:802:2107::/64
    • Subnet IPv6 gateway: 2407:c080:802:2107::1

    Destination

    • IPv4 address: 10.0.2.3
    • IPv6 address: 2407:c080:802:2108:96ec:3c49:391a:5ebc

    N/A

  2. Log in to the source ECS.

    For details, see How Do I Log In to My ECS?

  3. Check whether the ECSs have IPv6 enabled and have IPv6 addresses.

    Perform this step for both the source and destination ECSs to ensure that the ECSs have IPv6 addresses. Otherwise, the ECSs cannot communicate with each other using IPv6 addresses.

    ECSs in this example run CentOS 8.0 64bit or Huawei Cloud EulerOS 2.0 Standard 64 bit. For details about how to obtain IPv6 addresses for ECSs running other OSs, see Linux (Manually Enabling Dynamic Assignment of IPv6 Addresses).

    1. Check whether the ECS has IPv6 addresses:

      ip addr

      In the following command output, eth0 and eth1 are the network interfaces of the ECS. Each network interface has one inet6 entry starting with fe80. This indicates that the ECS has IPv6 enabled but does not have IPv6 addresses assigned. In this case, perform 3.b to 3.g to obtain IPv6 addresses.
      [root@ecs-resource ~]# ip addr
      ...
      2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
          link/ether fa:16:3e:72:72:f7 brd ff:ff:ff:ff:ff:ff
          inet 10.0.0.133/24 brd 10.0.0.255 scope global dynamic noprefixroute eth0
             valid_lft 315359994sec preferred_lft 315359994sec
          inet6 fe80::f816:3eff:fe72:72f7/64 scope link noprefixroute 
             valid_lft forever preferred_lft forever
      3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
          link/ether fa:16:3e:72:73:ea brd ff:ff:ff:ff:ff:ff
          inet 10.0.1.120/24 brd 10.0.1.255 scope global dynamic noprefixroute eth1
             valid_lft 315359994sec preferred_lft 315359994sec
          inet6 fe80::f816:3eff:fe72:73ea/64 scope link noprefixroute 
             valid_lft forever preferred_lft forever
    2. Query the network interface names of the source ECS:

      ifconfig

      Search for the network interface names based on IP addresses.
      • The IPv4 address of the primary network interface is 10.0.0.133, and its name is eth0.
      • The IPv4 address of the extended network interface is 10.0.1.120, and its name is eth1.
      [root@ecs-resource ~]# ifconfig
      eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
              inet 10.0.0.133  netmask 255.255.255.0  broadcast 10.0.0.255
              inet6 fe80::f816:3eff:fe72:72f7  prefixlen 64  scopeid 0x20<link>
              ether fa:16:3e:72:72:f7  txqueuelen 1000  (Ethernet)
              RX packets 50917  bytes 71068144 (67.7 MiB)
              RX errors 0  dropped 0  overruns 0  frame 0
              TX packets 4969  bytes 1123356 (1.0 MiB)
              TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
      
      eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
              inet 10.0.1.120  netmask 255.255.255.0  broadcast 10.0.1.255
              inet6 fe80::f816:3eff:fe72:73ea  prefixlen 64  scopeid 0x20<link>
              ether fa:16:3e:72:73:ea  txqueuelen 1000  (Ethernet)
              RX packets 21  bytes 3190 (3.1 KiB)
              RX errors 0  dropped 0  overruns 0  frame 0
              TX packets 26  bytes 2934 (2.8 KiB)
              TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
      ...
    3. Configure the ifcfg file of the primary network interface.
      1. Run the following command to open the ifcfg file of the primary network interface:

        vi /etc/sysconfig/network-scripts/ifcfg-<Primary-network-interface-name>

        The name of the primary network interface is obtained in 3.b.

        Example command:

        vi /etc/sysconfig/network-scripts/ifcfg-eth0

      2. Press i to enter the editing mode.
      3. Add the following content to the end of the file:
        IPV6INIT="yes"
        DHCPV6C="yes"
      4. Press ESC to exit and enter :wq! to save the configuration.
    4. Configure the ifcfg file of the extended network interface.
      1. Run the following command to open the ifcfg file of the extended network interface:

        vi /etc/sysconfig/network-scripts/ifcfg-<Extended-network-interface-name>

        The name of the extended network interface is obtained in 3.b.

        Example command:

        vi /etc/sysconfig/network-scripts/ifcfg-eth1

      2. Press i to enter the editing mode.
      3. Add the following content to the end of the file:
        IPV6INIT="yes"
        DHCPV6C="yes"
      4. Press ESC to exit and enter :wq! to save the configuration.
    5. Edit the /etc/sysconfig/network file.
      1. Run the following command to open the /etc/sysconfig/network file:

        vi /etc/sysconfig/network

      2. Press i to enter the editing mode.
      3. Add the following content to the end of the file:
        NETWORKING_IPV6="yes"
      4. Press ESC to exit and enter :wq! to save the configuration.
    6. Run the following command to restart the network service for the configuration to take effect:

      systemctl restart NetworkManager

    7. Check whether the ECS has IPv6 addresses:

      ip addr

      In the following command output, each network interface has an additional inet6 entry starting with 2407, followed by an entry starting with fe80. This indicates that the ECS has IPv6 addresses.
      [root@ecs-resource ~]# ip addr
      ...
      2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
          link/ether fa:16:3e:72:72:f7 brd ff:ff:ff:ff:ff:ff
          inet 10.0.0.133/24 brd 10.0.0.255 scope global dynamic noprefixroute eth0
             valid_lft 315359994sec preferred_lft 315359994sec
          inet6 2407:c080:802:1f85:918b:9039:41b2:24a8/128 scope global dynamic noprefixroute 
             valid_lft 7194sec preferred_lft 7194sec
          inet6 fe80::f816:3eff:fe72:72f7/64 scope link noprefixroute 
             valid_lft forever preferred_lft forever
      3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
          link/ether fa:16:3e:72:73:ea brd ff:ff:ff:ff:ff:ff
          inet 10.0.1.120/24 brd 10.0.1.255 scope global dynamic noprefixroute eth1
             valid_lft 315359994sec preferred_lft 315359994sec
          inet6 2407:c080:802:2107:ab85:4a27:d20:2119/128 scope global dynamic noprefixroute 
             valid_lft 7195sec preferred_lft 7195sec
          inet6 fe80::f816:3eff:fe72:73ea/64 scope link noprefixroute 
             valid_lft forever preferred_lft forever
    8. Log in to the destination ECS and obtain an IPv6 address by performing operations from 3.a to 3.g.
  4. Log in to the source ECS and check whether it can use its primary network interface to communicate with the destination ECS:

    Before configuring policy-based routes, ensure that the source ECS can use its primary network interface to communicate with the destination ECS.

    ping6 -I <IPv6-address-of-the-primary-network-interface-on-the-source-ECS> <IPv6-address-of-the-network-interface-on-the-destination-ECS>

    Example command:

    ping6 -I 2407:c080:802:1f85:918b:9039:41b2:24a8 2407:c080:802:2108:96ec:3c49:391a:5ebc

    If information similar to the following is displayed, the source ECS can use its primary network interface to communicate with the destination ECS.
    [root@ecs-resource ~]# ping6 -I 2407:c080:802:1f85:918b:9039:41b2:24a8 2407:c080:802:2108:96ec:3c49:391a:5ebc
    PING 2407:c080:802:2108:96ec:3c49:391a:5ebc(2407:c080:802:2108:96ec:3c49:391a:5ebc) from 2407:c080:802:1f85:918b:9039:41b2:24a8 : 56 data bytes
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=1 ttl=64 time=0.283 ms
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=2 ttl=64 time=0.212 ms
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=3 ttl=64 time=0.122 ms
    ^C
    --- 2407:c080:802:2108:96ec:3c49:391a:5ebc ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2050ms
    rtt min/avg/max/mdev = 0.122/0.205/0.283/0.065 ms
  5. Create an automation script to configure IPv6 routes:
    1. Create the automation configuration script file 15-policy-route.sh:

      vi /etc/NetworkManager/dispatcher.d/15-policy-route.sh

    2. Press i to enter the editing mode.
    3. Add the automation script to the file.
      #!/bin/bash
      
      if [ "$2" != "up" ]; then
          exit 0
      fi
      
      interface=$1
      
      check_route_table() {
          local route_table_id=$1
          local ip_version=$2
          local max_attempts=100
          local attempts=0
      
          while [ $attempts -lt $max_attempts ]; do
              output=$(ip -$ip_version route show table $route_table_id &>/dev/null)
              if [ $? -ne 0 ] || [ -z "$output" ]; then
                  break
              else
                  route_table_id=$((route_table_id + 1))
                  attempts=$((attempts + 1))
              fi
          done
      
          echo $route_table_id
      }
      
      add_ipv6_route_table() {
          local DEFAULT_IPV6_ROUTE_TABLE_ID=1100
          v6_route_table_id=$(ip -6 route show table all | grep -F "default via $v6_gateway dev $interface table" | grep -oP "table \K\d+")
          if [ -z $v6_route_table_id ]; then
              interface_number=$(echo $interface | grep -o '[0-9]*$')
              if [ -z "$interface_number" ]; then
                  v6_route_table_id=$DEFAULT_IPV6_ROUTE_TABLE_ID
              else
                  v6_route_table_id=$((DEFAULT_IPV6_ROUTE_TABLE_ID + interface_number))
              fi
      
              v6_route_table_id=$(check_route_table $v6_route_table_id 6)
      
              echo "add policy route for dev: $interface table: $v6_route_table_id v6_subnet: $v6_subnet v6_gateway: $v6_gateway"
      
              ip -6 route add default via $v6_gateway dev $interface table $v6_route_table_id
              ip -6 route add $v6_subnet dev $interface table $v6_route_table_id
          fi
      }
      
      generate_ipv6_policy_route() {
          IPV6INIT=$(awk -F= '/^IPV6INIT=/{gsub(/"/, ""); print $2}' "/etc/sysconfig/network-scripts/ifcfg-$interface" | tr -d ' ' | tail -n 1)
          if [ "$IPV6INIT" != "yes" ]; then
              echo "$interface IPV6INIT is not set to yes, skip IPv6 policy route configurate."
              return 0
          fi
      
          for ((x=0; x<10; x++)); do
              if (ip address show $interface | grep -F "inet6" | grep -F "dynamic"); then
                  v6_subnet=$(nmcli device show $interface | grep -F 'IP6.ROUTE' | grep -F 'nh = ::'| grep -v 'dst = fe80' | grep -v '/128' | cut -d'=' -f2 | cut -d',' -f1 | tr -d ' ' | head -n 1)
                  v6_gateway=$(ipcalc -6 -i $v6_subnet | awk '/HostMin/ {print $2}')1
      
                  add_ipv6_route_table
                  nmcli device show $interface | grep -F 'IP6.ADDRESS' | grep -v "/64" | while read -r line; do
                      IP=$(echo $line | awk '{print $2}' | cut -d'/' -f1)
                      if ip -6 rule list | grep -F "$v6_route_table_id" | grep -q "$IP"; then
                          echo "ip rule already exists for $IP with table $v6_route_table_id"
                          continue
                      fi
      
                      echo "Adding rule for $IP on $interface with table $v6_route_table_id"
                      ip -6 rule add from $IP table $v6_route_table_id
                  done
                  break
              fi
                sleep 1
          done
      }
      
      generate_ipv6_policy_route
    4. Press ESC to exit and enter :wq! to save the configuration.
    5. Check the permissions on the automatic configuration script file 15-policy-route.sh:

      ll /etc/NetworkManager/dispatcher.d/

      Information similar to the following is displayed. The permission on 15-policy-route.sh is -rw-r--r--, which is different from that on other system files, for example, permission -rwxr-xr-x on the file 10-ifcfg-rh-routes.sh.
      [root@ecs-resource ~]# ll /etc/NetworkManager/dispatcher.d/
      total 36
      -rwxr-xr-x. 1 root root 3840 Feb 26 17:45 10-ifcfg-rh-routes.sh
      -rwxr-xr-x. 1 root root 1062 Feb 26 17:45 11-dhclient
      -rw-r--r--  1 root root 2515 Jun 18 15:13 15-policy-route.sh
      -rwxr-xr-x. 1 root root 1412 Feb 26 17:45 20-chrony-dhcp
      -rwxr-xr-x. 1 root root  455 Feb 26 17:45 20-chrony-onoffline
      -rwxrwxr-x  1 root root  719 May 10  2019 hook-network-manager
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 no-wait.d
      drwxr-xr-x. 2 root root 4096 Feb 26 17:45 pre-down.d
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 pre-up.d
    6. Grant permissions on the automation configuration script file 15-policy-route.sh:

      sudo chown root:root /etc/NetworkManager/dispatcher.d/15-policy-route.sh

      sudo chmod 755 /etc/NetworkManager/dispatcher.d/15-policy-route.sh

    7. Check the permissions on the automatic configuration script file 15-policy-route.sh again:

      ll /etc/NetworkManager/dispatcher.d/

      Information similar to the following is displayed. The permission on 15-policy-route.sh is -rwxr-xr-x.
      [root@ecs-resource ~]# ll /etc/NetworkManager/dispatcher.d/
      total 36
      -rwxr-xr-x. 1 root root 3840 Feb 26 17:45 10-ifcfg-rh-routes.sh
      -rwxr-xr-x. 1 root root 1062 Feb 26 17:45 11-dhclient
      -rwxr-xr-x  1 root root 2019 Jun 18 12:21 15-policy-route.sh
      -rwxr-xr-x. 1 root root 1412 Feb 26 17:45 20-chrony-dhcp
      -rwxr-xr-x. 1 root root  455 Feb 26 17:45 20-chrony-onoffline
      -rwxrwxr-x  1 root root  719 May 10  2019 hook-network-manager
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 no-wait.d
      drwxr-xr-x. 2 root root 4096 Feb 26 17:45 pre-down.d
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 pre-up.d
    8. Restart the network service to execute the 15-policy-route.sh script:

      systemctl restart NetworkManager

      Before restarting the network service, ensure that services are not affected.

  6. Check whether the policy-based routes are added for the network interfaces with IPv6 addresses.

    ip -6 rule

    ip -6 route show table 1100

    ip -6 route show table 1101

    table 1100 is the route table name of the primary network interface, and table 1101 is the route table name of the extended network interface.

    If information similar to the following is displayed, the policy-based routes have been added for the network interfaces with IPv6 addresses.
    [root@ecs-resource ~]# ip -6 rule
    0:      from all lookup local
    32764:  from 2407:c080:802:2107:ab85:4a27:d20:2119 lookup 1101
    32765:  from 2407:c080:802:1f85:918b:9039:41b2:24a8 lookup 1100
    32766:  from all lookup main
    [root@ecs-resource ~]# ip -6 route show table 1100
    2407:c080:802:1f85::/64 dev eth0 metric 1024 pref medium
    default via 2407:c080:802:1f85::1 dev eth0 metric 1024 pref medium
    [root@ecs-resource ~]# ip -6 route show table 1101
    2407:c080:802:2107::/64 dev eth1 metric 1024 pref medium
    default via 2407:c080:802:2107::1 dev eth1 metric 1024 pref medium
  7. Check whether the source and destination ECSs can communicate with each other using IPv6 addresses.

    ping -6 -I <IPv6-address-of-the-primary-network-interface-on-the-source-ECS> <IPv6-address-of-the-network-interface-on-the-destination-ECS>

    ping -6 -I <IPv6-address-of-the-extended-network-interface-on-the-source-ECS> <IPv6-address-of-the-network-interface-on-the-destination-ECS>

    Example commands:

    ping -6 -I 2407:c080:802:1f85:918b:9039:41b2:24a8 2407:c080:802:2108:96ec:3c49:391a:5ebc

    ping -6 -I 2407:c080:802:2107:ab85:4a27:d20:2119 2407:c080:802:2108:96ec:3c49:391a:5ebc

    If information similar to the following is displayed, both the IPv6 addresses of the source ECS can communicate with the destination ECS, indicating that the IPv6 policy-based routes are successfully configured.
    [root@ecs-resource ~]# ping -6 -I 2407:c080:802:1f85:918b:9039:41b2:24a8 2407:c080:802:2108:96ec:3c49:391a:5ebc
    PING 2407:c080:802:2108:96ec:3c49:391a:5ebc(2407:c080:802:2108:96ec:3c49:391a:5ebc) from 2407:c080:802:1f85:918b:9039:41b2:24a8 : 56 data bytes
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=1 ttl=64 time=0.328 ms
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=2 ttl=64 time=0.209 ms
    ^C
    --- 2407:c080:802:2108:96ec:3c49:391a:5ebc ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1016ms
    rtt min/avg/max/mdev = 0.209/0.268/0.328/0.059 ms
    [root@ecs-resource ~]# ping -6 -I 2407:c080:802:2107:ab85:4a27:d20:2119 2407:c080:802:2108:96ec:3c49:391a:5ebc
    PING 2407:c080:802:2108:96ec:3c49:391a:5ebc(2407:c080:802:2108:96ec:3c49:391a:5ebc) from 2407:c080:802:2107:ab85:4a27:d20:2119 : 56 data bytes
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=1 ttl=64 time=0.345 ms
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=2 ttl=64 time=0.203 ms
    ^C
    --- 2407:c080:802:2108:96ec:3c49:391a:5ebc ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1051ms
    rtt min/avg/max/mdev = 0.203/0.274/0.345/0.071 ms

Configuring Policy-based Routes for a Linux ECS with Both IPv4 and IPv6 Addresses

  1. Collect the information, such as IPv4 and IPv6 addresses, about ECS network interfaces for configuring policy-based routes.

    For details, see Collecting ECS Network Information.

    In this example, the network information of the ECS is shown in Table 3.

    Table 3 Linux ECSs using IPv4 and IPv6 addresses

    Type

    Primary Network Interface

    Extended Network Interface

    Source

    • IPv4 address: 10.0.0.133
    • IPv6 address: 2407:c080:802:1f85:918b:9039:41b2:24a8
    • Subnet IPv6 CIDR block: 2407:c080:802:1f85::/64
    • Subnet IPv6 gateway: 2407:c080:802:1f85::1
    • IPv4 address: 10.0.1.120
    • IPv6 address: 2407:c080:802:2107:ab85:4a27:d20:2119
    • Subnet IPv6 CIDR block: 2407:c080:802:2107::/64
    • Subnet IPv6 gateway: 2407:c080:802:2107::1

    Destination

    • IPv4 address: 10.0.2.3
    • IPv6 address: 2407:c080:802:2108:96ec:3c49:391a:5ebc

    N/A

  2. Log in to the source ECS.

    For details, see How Do I Log In to My ECS?

  3. Check whether the source ECS can use its primary network interface to communicate with the destination ECS using IPv4 addresses:

    Before configuring policy-based routes, ensure that the source ECS can use its primary network interface to communicate with the destination ECS.

    ping -I <IPv4-address-of-the-primary-network-interface-on-the-source-ECS> <IPv4-address-of-destination-ECS>

    Example command:

    ping -I 10.0.0.115 10.0.2.12

    If information similar to the following is displayed, the source ECS can use its primary network interface to communicate with the destination ECS.
    [root@ecs-resource ~]# ping -I 10.0.0.133 10.0.2.3
    PING 10.0.2.3 (10.0.2.3) from 10.0.0.133 : 56(84) bytes of data.
    64 bytes from 10.0.2.3: icmp_seq=1 ttl=64 time=0.261 ms
    64 bytes from 10.0.2.3: icmp_seq=2 ttl=64 time=0.219 ms
    ^C
    --- 10.0.2.3 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1032ms
    rtt min/avg/max/mdev = 0.219/0.240/0.261/0.021 ms
  4. Check whether the ECSs have IPv6 enabled and have IPv6 addresses.

    Perform this step for both the source and destination ECSs to ensure that the ECSs have IPv6 addresses. Otherwise, the ECSs cannot communicate with each other using IPv6 addresses.

    ECSs in this example run CentOS 8.0 64bit or Huawei Cloud EulerOS 2.0 Standard 64 bit. For details about how to obtain IPv6 addresses for ECSs running other OSs, see Linux (Manually Enabling Dynamic Assignment of IPv6 Addresses).

    1. Check whether the ECS has IPv6 addresses:

      ip addr

      In the following command output, eth0 and eth1 are the network interfaces of the ECS. Each network interface has one inet6 entry starting with fe80. This indicates that the ECS has IPv6 enabled but does not have IPv6 addresses assigned. In this case, perform 4.b to 4.g to obtain IPv6 addresses.
      [root@ecs-resource ~]# ip addr
      ...
      2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
          link/ether fa:16:3e:72:72:f7 brd ff:ff:ff:ff:ff:ff
          inet 10.0.0.133/24 brd 10.0.0.255 scope global dynamic noprefixroute eth0
             valid_lft 315359994sec preferred_lft 315359994sec
          inet6 fe80::f816:3eff:fe72:72f7/64 scope link noprefixroute 
             valid_lft forever preferred_lft forever
      3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
          link/ether fa:16:3e:72:73:ea brd ff:ff:ff:ff:ff:ff
          inet 10.0.1.120/24 brd 10.0.1.255 scope global dynamic noprefixroute eth1
             valid_lft 315359994sec preferred_lft 315359994sec
          inet6 fe80::f816:3eff:fe72:73ea/64 scope link noprefixroute 
             valid_lft forever preferred_lft forever
    2. Query the network interface names of the source ECS:

      ifconfig

      Search for the network interface names based on IP addresses.
      • The IPv4 address of the primary network interface is 10.0.0.133, and its name is eth0.
      • The IPv4 address of the extended network interface is 10.0.1.120, and its name is eth1.
      [root@ecs-resource ~]# ifconfig
      eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
              inet 10.0.0.133  netmask 255.255.255.0  broadcast 10.0.0.255
              inet6 fe80::f816:3eff:fe72:72f7  prefixlen 64  scopeid 0x20<link>
              ether fa:16:3e:72:72:f7  txqueuelen 1000  (Ethernet)
              RX packets 50917  bytes 71068144 (67.7 MiB)
              RX errors 0  dropped 0  overruns 0  frame 0
              TX packets 4969  bytes 1123356 (1.0 MiB)
              TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
      
      eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
              inet 10.0.1.120  netmask 255.255.255.0  broadcast 10.0.1.255
              inet6 fe80::f816:3eff:fe72:73ea  prefixlen 64  scopeid 0x20<link>
              ether fa:16:3e:72:73:ea  txqueuelen 1000  (Ethernet)
              RX packets 21  bytes 3190 (3.1 KiB)
              RX errors 0  dropped 0  overruns 0  frame 0
              TX packets 26  bytes 2934 (2.8 KiB)
              TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
      ...
    3. Configure the ifcfg file of the primary network interface.
      1. Run the following command to open the ifcfg file of the primary network interface:

        vi /etc/sysconfig/network-scripts/ifcfg-<Primary-network-interface-name>

        The name of the primary network interface is obtained in 4.b.

        Example command:

        vi /etc/sysconfig/network-scripts/ifcfg-eth0

      2. Press i to enter the editing mode.
      3. Add the following content to the end of the file:
        IPV6INIT="yes"
        DHCPV6C="yes"
      4. Press ESC to exit and enter :wq! to save the configuration.
    4. Configure the ifcfg file of the extended network interface.
      1. Run the following command to open the ifcfg file of the extended network interface:

        vi /etc/sysconfig/network-scripts/ifcfg-<Extended-network-interface-name>

        The name of the extended network interface is obtained in 4.b.

        Example command:

        vi /etc/sysconfig/network-scripts/ifcfg-eth1

      2. Press i to enter the editing mode.
      3. Add the following content to the end of the file:
        IPV6INIT="yes"
        DHCPV6C="yes"
      4. Press ESC to exit and enter :wq! to save the configuration.
    5. Edit the /etc/sysconfig/network file.
      1. Run the following command to open the /etc/sysconfig/network file:

        vi /etc/sysconfig/network

      2. Press i to enter the editing mode.
      3. Add the following content to the end of the file:
        NETWORKING_IPV6="yes"
      4. Press ESC to exit and enter :wq! to save the configuration.
    6. Run the following command to restart the network service for the configuration to take effect:

      systemctl restart NetworkManager

    7. Check whether the ECS has IPv6 addresses:

      ip addr

      In the following command output, each network interface has an additional inet6 entry starting with 2407, followed by an entry starting with fe80. This indicates that the ECS has IPv6 addresses.
      [root@ecs-resource ~]# ip addr
      ...
      2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
          link/ether fa:16:3e:72:72:f7 brd ff:ff:ff:ff:ff:ff
          inet 10.0.0.133/24 brd 10.0.0.255 scope global dynamic noprefixroute eth0
             valid_lft 315359994sec preferred_lft 315359994sec
          inet6 2407:c080:802:1f85:918b:9039:41b2:24a8/128 scope global dynamic noprefixroute 
             valid_lft 7194sec preferred_lft 7194sec
          inet6 fe80::f816:3eff:fe72:72f7/64 scope link noprefixroute 
             valid_lft forever preferred_lft forever
      3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
          link/ether fa:16:3e:72:73:ea brd ff:ff:ff:ff:ff:ff
          inet 10.0.1.120/24 brd 10.0.1.255 scope global dynamic noprefixroute eth1
             valid_lft 315359994sec preferred_lft 315359994sec
          inet6 2407:c080:802:2107:ab85:4a27:d20:2119/128 scope global dynamic noprefixroute 
             valid_lft 7195sec preferred_lft 7195sec
          inet6 fe80::f816:3eff:fe72:73ea/64 scope link noprefixroute 
             valid_lft forever preferred_lft forever
    8. Log in to the destination ECS and obtain an IPv6 address by performing operations from 4.a to 4.g.
  5. Log in to the source ECS and check whether it can use its primary network interface to communicate with the destination ECS:

    Before configuring policy-based routes, ensure that the source ECS can use its primary network interface to communicate with the destination ECS.

    ping6 -I <IPv6-address-of-the-primary-network-interface-on-the-source-ECS> <IPv6-address-of-the-network-interface-on-the-destination-ECS>

    Example command:

    ping6 -I 2407:c080:802:1f85:918b:9039:41b2:24a8 2407:c080:802:2108:96ec:3c49:391a:5ebc

    If information similar to the following is displayed, the source ECS can use its primary network interface to communicate with the destination ECS.
    [root@ecs-resource ~]# ping6 -I 2407:c080:802:1f85:918b:9039:41b2:24a8 2407:c080:802:2108:96ec:3c49:391a:5ebc
    PING 2407:c080:802:2108:96ec:3c49:391a:5ebc(2407:c080:802:2108:96ec:3c49:391a:5ebc) from 2407:c080:802:1f85:918b:9039:41b2:24a8 : 56 data bytes
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=1 ttl=64 time=0.283 ms
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=2 ttl=64 time=0.212 ms
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=3 ttl=64 time=0.122 ms
    ^C
    --- 2407:c080:802:2108:96ec:3c49:391a:5ebc ping statistics ---
    3 packets transmitted, 3 received, 0% packet loss, time 2050ms
    rtt min/avg/max/mdev = 0.122/0.205/0.283/0.065 ms
  6. Create an automation script to configure both IPv4 and IPv6 routes:
    1. Create the automation configuration script file 15-policy-route.sh:

      vi /etc/NetworkManager/dispatcher.d/15-policy-route.sh

    2. Press i to enter the editing mode.
    3. Add the automation script to the file.
      #!/bin/bash
      
      if [ "$2" != "up" ]; then
          exit 0
      fi
      
      interface=$1
      
      check_route_table() {
          local route_table_id=$1
          local ip_version=$2
          local max_attempts=100
          local attempts=0
      
          while [ $attempts -lt $max_attempts ]; do
              output=$(ip -$ip_version route show table $route_table_id &>/dev/null)
              if [ $? -ne 0 ] || [ -z "$output" ]; then
                  break
              else
                  route_table_id=$((route_table_id + 1))
                  attempts=$((attempts + 1))
              fi
          done
      
          echo $route_table_id
      }
      
      add_ipv4_route_table() {
          local DEFAULT_IPV4_ROUTE_TABLE_ID=1000
          v4_route_table_id=$(ip route show table all | grep -F "default via $gateway dev $interface table" | awk '{print $NF}')
          if [ -z $v4_route_table_id ]; then
              interface_number=$(echo $interface | grep -o '[0-9]*$')
              if [ -z "$interface_number" ]; then
                  v4_route_table_id="$DEFAULT_IPV4_ROUTE_TABLE_ID"
              else
                  v4_route_table_id=$((DEFAULT_IPV4_ROUTE_TABLE_ID + interface_number))
              fi
      
              v4_route_table_id=$(check_route_table $v4_route_table_id 4)
      
              echo "add policy route for dev: $interface table: $v4_route_table_id subnet: $subnet gateway: $gateway"
      
              ip route add default via $gateway dev $interface table $v4_route_table_id
              ip route add $subnet dev $interface table $v4_route_table_id
          fi
      }
      
      generate_ipv4_policy_route() {
          subnet=$(nmcli device show $interface | grep -F 'IP4.ROUTE' | grep -F 'nh = 0.0.0.0' | cut -d'=' -f2 | cut -d',' -f1 | tr -d ' ' | head -n 1)
          gateway=$(ipcalc -i $subnet | awk '/HostMin/ {print $2}')
      
          add_ipv4_route_table
      
          nmcli device show $interface | grep -F 'IP4.ADDRESS' | while read -r line; do
              IP=$(echo $line | awk '{print $2}' | cut -d'/' -f1)
              if ip rule list | grep -F "$v4_route_table_id" | grep -q "$IP"; then
                  echo "ip rule already exists for $IP with table $v4_route_table_id"
                  continue
              fi
      
              echo "Adding rule for $IP on $interface with table $v4_route_table_id"
              ip rule add from $IP table $v4_route_table_id
          done
      }
      
      generate_ipv4_policy_route
      
      add_ipv6_route_table() {
          local DEFAULT_IPV6_ROUTE_TABLE_ID=1100
          v6_route_table_id=$(ip -6 route show table all | grep -F "default via $v6_gateway dev $interface table" | grep -oP "table \K\d+")
          if [ -z $v6_route_table_id ]; then
              interface_number=$(echo $interface | grep -o '[0-9]*$')
              if [ -z "$interface_number" ]; then
                  v6_route_table_id=$DEFAULT_IPV6_ROUTE_TABLE_ID
              else
                  v6_route_table_id=$((DEFAULT_IPV6_ROUTE_TABLE_ID + interface_number))
              fi
      
              v6_route_table_id=$(check_route_table $v6_route_table_id 6)
      
              echo "add policy route for dev: $interface table: $v6_route_table_id v6_subnet: $v6_subnet v6_gateway: $v6_gateway"
      
              ip -6 route add default via $v6_gateway dev $interface table $v6_route_table_id
              ip -6 route add $v6_subnet dev $interface table $v6_route_table_id
          fi
      }
      
      generate_ipv6_policy_route() {
          IPV6INIT=$(awk -F= '/^IPV6INIT=/{gsub(/"/, ""); print $2}' "/etc/sysconfig/network-scripts/ifcfg-$interface" | tr -d ' ' | tail -n 1)
          if [ "$IPV6INIT" != "yes" ]; then
              echo "$interface IPV6INIT is not set to yes, skip IPv6 policy route configurate."
              return 0
          fi
      
          for ((x=0; x<10; x++)); do
              if (ip address show $interface | grep -F "inet6" | grep -F "dynamic"); then
                  v6_subnet=$(nmcli device show $interface | grep -F 'IP6.ROUTE' | grep -F 'nh = ::'| grep -v 'dst = fe80' | grep -v '/128' | cut -d'=' -f2 | cut -d',' -f1 | tr -d ' ' | head -n 1)
                  v6_gateway=$(ipcalc -6 -i $v6_subnet | awk '/HostMin/ {print $2}')1
      
                  add_ipv6_route_table
                  nmcli device show $interface | grep -F 'IP6.ADDRESS' | grep -v "/64" | while read -r line; do
                      IP=$(echo $line | awk '{print $2}' | cut -d'/' -f1)
                      if ip -6 rule list | grep -F "$v6_route_table_id" | grep -q "$IP"; then
                          echo "ip rule already exists for $IP with table $v6_route_table_id"
                          continue
                      fi
      
                      echo "Adding rule for $IP on $interface with table $v6_route_table_id"
                      ip -6 rule add from $IP table $v6_route_table_id
                  done
                  break
              fi
                sleep 1
          done
      }
      
      generate_ipv6_policy_route
    4. Press ESC to exit and enter :wq! to save the configuration.
    5. Check the permissions on the automatic configuration script file 15-policy-route.sh:

      ll /etc/NetworkManager/dispatcher.d/

      Information similar to the following is displayed. The permission on 15-policy-route.sh is -rw-r--r--, which is different from that on other system files, for example, permission -rwxr-xr-x on the file 10-ifcfg-rh-routes.sh.
      [root@ecs-resource ~]# ll /etc/NetworkManager/dispatcher.d/
      total 36
      -rwxr-xr-x. 1 root root 3840 Feb 26 17:45 10-ifcfg-rh-routes.sh
      -rwxr-xr-x. 1 root root 1062 Feb 26 17:45 11-dhclient
      -rw-r--r--  1 root root 2515 Jun 18 15:13 15-policy-route.sh
      -rwxr-xr-x. 1 root root 1412 Feb 26 17:45 20-chrony-dhcp
      -rwxr-xr-x. 1 root root  455 Feb 26 17:45 20-chrony-onoffline
      -rwxrwxr-x  1 root root  719 May 10  2019 hook-network-manager
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 no-wait.d
      drwxr-xr-x. 2 root root 4096 Feb 26 17:45 pre-down.d
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 pre-up.d
    6. Grant permissions on the automation configuration script file 15-policy-route.sh:

      sudo chown root:root /etc/NetworkManager/dispatcher.d/15-policy-route.sh

      sudo chmod 755 /etc/NetworkManager/dispatcher.d/15-policy-route.sh

    7. Check the permissions on the automatic configuration script file 15-policy-route.sh again:

      ll /etc/NetworkManager/dispatcher.d/

      Information similar to the following is displayed. The permission on 15-policy-route.sh is -rwxr-xr-x.
      [root@ecs-resource ~]# ll /etc/NetworkManager/dispatcher.d/
      total 36
      -rwxr-xr-x. 1 root root 3840 Feb 26 17:45 10-ifcfg-rh-routes.sh
      -rwxr-xr-x. 1 root root 1062 Feb 26 17:45 11-dhclient
      -rwxr-xr-x  1 root root 2019 Jun 18 12:21 15-policy-route.sh
      -rwxr-xr-x. 1 root root 1412 Feb 26 17:45 20-chrony-dhcp
      -rwxr-xr-x. 1 root root  455 Feb 26 17:45 20-chrony-onoffline
      -rwxrwxr-x  1 root root  719 May 10  2019 hook-network-manager
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 no-wait.d
      drwxr-xr-x. 2 root root 4096 Feb 26 17:45 pre-down.d
      drwxr-xr-x. 2 root root 4096 Apr 18 17:12 pre-up.d
    8. Restart the network service to execute the 15-policy-route.sh script:

      systemctl restart NetworkManager

      Before restarting the network service, ensure that services are not affected.

  7. Check whether the policy-based IPv4 routes are added.

    ip rule

    ip route show table 1000

    ip route show table 1001

    table 1000 is the route table name of the primary network interface, and table 1001 is the route table name of the extended network interface.

    If information similar to the following is displayed, the policy-based routes have been added for the network interfaces with IPv4 addresses.
    [root@ecs-resource ~]# ip rule
    0:      from all lookup local
    32764:  from 10.0.1.120 lookup 1001
    32765:  from 10.0.0.133 lookup 1000
    32766:  from all lookup main
    32767:  from all lookup default
    [root@ecs-resource ~]# ip route show table 1000
    default via 10.0.0.1 dev eth0 
    10.0.0.0/24 dev eth0 scope link 
    [root@ecs-resource ~]# ip route show table 1001
    default via 10.0.1.1 dev eth1 
    10.0.1.0/24 dev eth1 scope link 
  8. Check whether the source and destination ECSs can communicate with each other using IPv4 addresses.

    ping -I <IPv4-address-of-the-primary-network-interface-on-the-source-ECS> <IPv4-address-of-the-network-interface-on-the-destination-ECS>

    ping -I <IPv4-address-of-the-extended-network-interface-on-the-source-ECS> <IPv4-address-of-the-network-interface-on-the-destination-ECS>

    Example commands:

    ping -I 10.0.0.133 10.0.2.3

    ping -I 10.0.1.120 10.0.2.3

    If information similar to the following is displayed, both the IPv4 addresses of the source ECS can communicate with the destination ECS, indicating that the IPv4 policy-based routes are successfully configured.
    [root@ecs-resource ~]# ping -I 10.0.0.133 10.0.2.3
    PING 10.0.2.3 (10.0.2.3) from 10.0.0.133 : 56(84) bytes of data.
    64 bytes from 10.0.2.3: icmp_seq=1 ttl=64 time=0.241 ms
    64 bytes from 10.0.2.3: icmp_seq=2 ttl=64 time=0.198 ms
    ^C
    --- 10.0.2.3 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1064ms
    rtt min/avg/max/mdev = 0.198/0.219/0.241/0.021 ms
    [root@ecs-resource ~]# ping -I 10.0.1.120 10.0.2.3
    PING 10.0.2.3 (10.0.2.3) from 10.0.1.120 : 56(84) bytes of data.
    64 bytes from 10.0.2.3: icmp_seq=1 ttl=64 time=0.242 ms
    64 bytes from 10.0.2.3: icmp_seq=2 ttl=64 time=0.184 ms
    ^C
    --- 10.0.2.3 ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1062ms
    rtt min/avg/max/mdev = 0.184/0.213/0.242/0.029 ms
  9. Check whether the policy-based IPv6 routes are added.

    ip -6 rule

    ip -6 route show table 1100

    ip -6 route show table 1101

    table 1100 is the route table name of the primary network interface, and table 1101 is the route table name of the extended network interface.

    If information similar to the following is displayed, the policy-based routes have been added for the network interfaces with IPv6 addresses.
    [root@ecs-resource ~]# ip -6 rule
    0:      from all lookup local
    32764:  from 2407:c080:802:2107:ab85:4a27:d20:2119 lookup 1101
    32765:  from 2407:c080:802:1f85:918b:9039:41b2:24a8 lookup 1100
    32766:  from all lookup main
    [root@ecs-resource ~]# ip -6 route show table 1100
    2407:c080:802:1f85::/64 dev eth0 metric 1024 pref medium
    default via 2407:c080:802:1f85::1 dev eth0 metric 1024 pref medium
    [root@ecs-resource ~]# ip -6 route show table 1101
    2407:c080:802:2107::/64 dev eth1 metric 1024 pref medium
    default via 2407:c080:802:2107::1 dev eth1 metric 1024 pref medium
  10. Check whether the source and destination ECSs can communicate with each other using IPv6 addresses.

    ping -6 -I <IPv6-address-of-the-primary-network-interface-on-the-source-ECS> <IPv6-address-of-the-network-interface-on-the-destination-ECS>

    ping -6 -I <IPv6-address-of-the-extended-network-interface-on-the-source-ECS> <IPv6-address-of-the-network-interface-on-the-destination-ECS>

    Example commands:

    ping -6 -I 2407:c080:802:1f85:918b:9039:41b2:24a8 2407:c080:802:2108:96ec:3c49:391a:5ebc

    ping -6 -I 2407:c080:802:2107:ab85:4a27:d20:2119 2407:c080:802:2108:96ec:3c49:391a:5ebc

    If information similar to the following is displayed, both the IPv6 addresses of the source ECS can communicate with the destination ECS, indicating that the IPv6 policy-based routes are successfully configured.
    [root@ecs-resource ~]# ping -6 -I 2407:c080:802:1f85:918b:9039:41b2:24a8 2407:c080:802:2108:96ec:3c49:391a:5ebc
    PING 2407:c080:802:2108:96ec:3c49:391a:5ebc(2407:c080:802:2108:96ec:3c49:391a:5ebc) from 2407:c080:802:1f85:918b:9039:41b2:24a8 : 56 data bytes
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=1 ttl=64 time=0.328 ms
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=2 ttl=64 time=0.209 ms
    ^C
    --- 2407:c080:802:2108:96ec:3c49:391a:5ebc ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1016ms
    rtt min/avg/max/mdev = 0.209/0.268/0.328/0.059 ms
    [root@ecs-resource ~]# ping -6 -I 2407:c080:802:2107:ab85:4a27:d20:2119 2407:c080:802:2108:96ec:3c49:391a:5ebc
    PING 2407:c080:802:2108:96ec:3c49:391a:5ebc(2407:c080:802:2108:96ec:3c49:391a:5ebc) from 2407:c080:802:2107:ab85:4a27:d20:2119 : 56 data bytes
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=1 ttl=64 time=0.345 ms
    64 bytes from 2407:c080:802:2108:96ec:3c49:391a:5ebc: icmp_seq=2 ttl=64 time=0.203 ms
    ^C
    --- 2407:c080:802:2108:96ec:3c49:391a:5ebc ping statistics ---
    2 packets transmitted, 2 received, 0% packet loss, time 1051ms
    rtt min/avg/max/mdev = 0.203/0.274/0.345/0.071 ms