Automatically Configuring IPv4 Policy-based Routes for a Linux ECS with Multiple Network Interfaces (Ubuntu)
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 Ubuntu 22.04.
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
- 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
- Log in to the source ECS.
For details, see How Do I Log In to My ECS?
- 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.262 ms 64 bytes from 10.0.2.12: icmp_seq=2 ttl=64 time=0.193 ms 64 bytes from 10.0.2.12: icmp_seq=3 ttl=64 time=0.086 ms ^C --- 10.0.2.12 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2045ms rtt min/avg/max/mdev = 0.086/0.180/0.262/0.072 ms
- Query the network interface names of the source ECS: 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:fe72:72e5 prefixlen 64 scopeid 0x20<link> ether fa:16:3e:72:72:e5 txqueuelen 1000 (Ethernet) RX packets 139035 bytes 201093027 (201.0 MB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 18669 bytes 1744334 (1.7 MB) 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:fe72:7329 prefixlen 64 scopeid 0x20<link> ether fa:16:3e:72:73:29 txqueuelen 1000 (Ethernet) RX packets 2 bytes 738 (738.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 35 bytes 2466 (2.4 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 - Create an automation configuration script to configure IPv4 routes.
- Create the automation configuration script file 15-policy-route.sh:
vi /etc/NetworkManager/dispatcher.d/15-policy-route.sh
- Press i to enter the editing mode.
- Add the automation configuration 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 } get_gateway_by_subnet() { subnet=$1 IFS='/' read -r ip mask <<< "$subnet" IFS='.' read -r ip1 ip2 ip3 ip4 <<< "$ip" gateway="$ip1.$ip2.$ip3.$((ip4+1))" echo $gateway } 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=$(get_gateway_by_subnet $subnet) 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 - Press ESC to exit and enter :wq! to save the configuration.
- 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 01-ifupdown*.root@ecs-resource:~# ll /etc/NetworkManager/dispatcher.d/ total 32 drwxr-xr-x 5 root root 4096 Nov 7 12:21 ./ drwxr-xr-x 7 root root 4096 Apr 22 2025 ../ -rwxr-xr-x 1 root root 2293 Dec 11 2024 01-ifupdown* -rw-r--r-- 1 root root 2317 Nov 7 12:21 15-policy-route.sh -rwxrwxr-x 1 root root 719 May 10 2019 hook-network-manager* drwxr-xr-x 2 root root 4096 Dec 11 2024 no-wait.d/ drwxr-xr-x 2 root root 4096 Dec 11 2024 pre-down.d/ drwxr-xr-x 2 root root 4096 Dec 11 2024 pre-up.d/
- 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
- 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 32 drwxr-xr-x 5 root root 4096 Nov 7 12:21 ./ drwxr-xr-x 7 root root 4096 Apr 22 2025 ../ -rwxr-xr-x 1 root root 2293 Dec 11 2024 01-ifupdown* -rwxr-xr-x 1 root root 2317 Nov 7 12:21 15-policy-route.sh* -rwxrwxr-x 1 root root 719 May 10 2019 hook-network-manager* drwxr-xr-x 2 root root 4096 Dec 11 2024 no-wait.d/ drwxr-xr-x 2 root root 4096 Dec 11 2024 pre-down.d/ drwxr-xr-x 2 root root 4096 Dec 11 2024 pre-up.d/
- 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.
- Create the automation configuration script file 15-policy-route.sh:
- Check whether the policy-based routes are added for the network interfaces with IPv4 addresses.
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
- 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.233 ms 64 bytes from 10.0.2.12: icmp_seq=2 ttl=64 time=0.177 ms 64 bytes from 10.0.2.12: icmp_seq=3 ttl=64 time=0.089 ms ^C --- 10.0.2.12 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2029ms rtt min/avg/max/mdev = 0.089/0.166/0.233/0.059 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.300 ms 64 bytes from 10.0.2.12: icmp_seq=2 ttl=64 time=0.194 ms 64 bytes from 10.0.2.12: icmp_seq=3 ttl=64 time=0.100 ms ^C --- 10.0.2.12 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2025ms rtt min/avg/max/mdev = 0.100/0.198/0.300/0.081 ms
Feedback
Was this page helpful?
Provide feedbackThank you very much for your feedback. We will continue working to improve the documentation.See the reply and handling status in My Cloud VOC.
For any further questions, feel free to contact us through the chatbot.
Chatbot