For an Elastic Compute Service (ECS) instance that runs Alibaba Cloud Linux 3, the default routing algorithm selects routes based on the destination IP addresses of packets. As a result, the system always uses the primary network interface controller (NIC), such as eth0, instead of a secondary NIC, such as eth1, to transmit the traffic that originates from the secondary NIC and is destined for the subnet of the secondary NIC. To resolve the preceding issue, you can configure policy-based routes to direct traffic based on source IP addresses.
Limits
Operating system requirements: Alibaba Cloud Linux 3.
Configure a policy-based route
By default, NetworkManager is used in Alibaba Cloud Linux 3 to configure NICs. To configure policy-based routes, we recommend that you use the nmcli tool provided by NetworkManager. This section describes how to configure a policy-based route for the eth1 secondary NIC.
Configure a persistent policy-based route
If you configure persistent policy-based routes on an ECS instance, the routes remain in effect even after you restart the instance.
Run the following command to create and open the
config_dual_traffic.shfile:sudo vim config_dual_traffic.shPress the
Ikey to enter Insert mode and copy the following content to theconfig_dual_traffic.shfile:#!/bin/bash # Target NIC name NIC=$1 # URL for metaserver BASE_URL="http://100.100.100.200/latest/meta-data/network/interfaces/macs" # MAC/IP address/netmask/gateway for NIC MAC=$(cat /sys/class/net/$NIC/address) IP_ADDRESS=$(curl $BASE_URL/$MAC/primary-ip-address) NETMASK=$(curl $BASE_URL/$MAC/netmask) GATEWAY=$(curl $BASE_URL/$MAC/gateway) # 255.255.255.0 to /24 netmask_to_cidr() { local binary_mask="" IFS='.' read -ra ADDR <<<"$NETMASK" for octet in "${ADDR[@]}"; do binary_mask+=$(echo "obase=2; $octet" | bc) done local cidr=0 for ((i=0; i<${#binary_mask}; i++)); do if [ "${binary_mask:$i:1}" == "1" ]; then ((cidr++)) fi done echo "$cidr" } CIDR=$(netmask_to_cidr $NETMASK) NETWORK_ADDRESS=$(ipcalc -n $IP_ADDRESS $NETMASK | cut -d= -f2) IP_CIDR="${NETWORK_ADDRESS}/${CIDR}" # Connection name for NIC CONNECTION_NAME=$(nmcli -g NAME,DEVICE connection show | grep $NIC | awk -F: '{print $1}') echo "NIC name: $NIC" echo "mac addrss: $MAC" echo "ip address: $IP_ADDRESS" echo "netmask: $NETMASK" echo "IP_CIDR: $IP_CIDR" echo "default gateway: $GATEWAY" echo "connection: $CONNECTION_NAME" nmcli connection modify "$CONNECTION_NAME" +ipv4.routing-rules "priority 100 from $IP_ADDRESS table 200" nmcli connection modify "$CONNECTION_NAME" +ipv4.routes "0.0.0.0/0 $GATEWAY table=200" nmcli connection modify "$CONNECTION_NAME" +ipv4.routes "$IP_CIDR table=200" nmcli connection up "$CONNECTION_NAME" echo "The dual network card sending network configuration is completed."Press the
Esckey, enter:wq, and then press theEnterkey to save and close the file.Run the following command to allow the policy-based route that is configured for the
eth1secondary NIC to take effect.Replace eth1 with the actual NIC name.
sudo sh config_dual_traffic.sh eth1Run the following commands to view the routing rules and route entries:
ip rule ip route show table 200The following command output indicates that the policy-based route is configured.

Configure a temporary policy-based route
If you configure temporary policy-based routes on an ECS instance, the routes become invalid after you restart the instance.
Run the following command to create and open the
config_dual_traffic.shfile:sudo vim config_dual_traffic.shPress the
Ikey to enter Insert mode and copy the following content to theconfig_dual_traffic.shfile:#!/bin/bash # Target NIC name NIC=$1 # URL for metaserver BASE_URL="http://100.100.100.200/latest/meta-data/network/interfaces/macs" # MAC/IP address/netmask/gateway for NIC MAC=$(cat /sys/class/net/$NIC/address) IP_ADDRESS=$(curl $BASE_URL/$MAC/primary-ip-address) NETMASK=$(curl $BASE_URL/$MAC/netmask) GATEWAY=$(curl $BASE_URL/$MAC/gateway) # 255.255.255.0 to /24 netmask_to_cidr() { local binary_mask="" IFS='.' read -ra ADDR <<<"$NETMASK" for octet in "${ADDR[@]}"; do binary_mask+=$(echo "obase=2; $octet" | bc) done local cidr=0 for ((i=0; i<${#binary_mask}; i++)); do if [ "${binary_mask:$i:1}" == "1" ]; then ((cidr++)) fi done echo "$cidr" } CIDR=$(netmask_to_cidr $NETMASK) NETWORK_ADDRESS=$(ipcalc -n $IP_ADDRESS $NETMASK | cut -d= -f2) IP_CIDR="${NETWORK_ADDRESS}/${CIDR}" # Device name for NIC DEVICE_NAME=$(nmcli -g NAME,DEVICE connection show | grep $NIC | awk -F: '{print $2}') echo "NIC name: $NIC" echo "mac addrss: $MAC" echo "ip address: $IP_ADDRESS" echo "netmask: $NETMASK" echo "IP_CIDR: $IP_CIDR" echo "default gateway: $GATEWAY" echo "device: $DEVICE_NAME" nmcli device modify "$DEVICE_NAME" +ipv4.routing-rules "priority 100 from $IP_ADDRESS table 200" nmcli device modify "$DEVICE_NAME" +ipv4.routes "0.0.0.0/0 $GATEWAY table=200" nmcli device modify "$DEVICE_NAME" +ipv4.routes "$IP_CIDR table=200" echo "The dual network card sending network configuration is completed."Press the
Esckey, enter:wq, and then press theEnterkey to save and close the file.Run the following command to allow the policy-based route that is configured for the
eth1secondary NIC to take effect.Replace eth1 with the actual NIC name.
sudo sh config_dual_traffic.sh eth1Run the following commands to view the routing rules and route entries:
ip rule ip route show table 200The following command output indicates that the policy-based route is configured.
