Chapter 27. Configuring a static route


Routing directs traffic between mutually-connected networks. In larger environments, administrators configure services so that routers dynamically learn about each other. In smaller ones, administrators often configure static routes to ensure traffic can reach its destination.

You need static routes to achieve a functioning communication among multiple networks if all of these conditions apply:

  • The traffic has to pass multiple networks.
  • The exclusive traffic flow through the default gateways is not sufficient.

The Example of a network that requires static routes section describes scenarios and how the traffic flows between different networks when you do not configure static routes.

You require static routes in this example because not all IP networks are directly connected through one router. Without the static routes, some networks cannot communicate with each other. Additionally, traffic from some networks flows only in one direction.

Note

The network topology in this example is artificial and only used to explain the concept of static routing. It is not a recommended topology in production environments.

For a functioning communication among all networks in this example, configure a static route to Raleigh (198.51.100.0/24) with next the hop Router 2 (203.0.113.10). The IP address of the next hop is the one of Router 2 in the data center network (203.0.113.0/24).

You can configure the static route as follows:

  • For a simplified configuration, set this static route only on Router 1. However, this increases the traffic on Router 1 because hosts from the data center (203.0.113.0/24) send traffic to Raleigh (198.51.100.0/24) always through Router 1 to Router 2.
  • For a more complex configuration, configure this static route on all hosts in the data center (203.0.113.0/24). All hosts in this subnet then send traffic directly to Router 2 (203.0.113.10) that is closer to Raleigh (198.51.100.0/24).

For more details between which networks traffic flows or not, see the explanations below the diagram.

In case that the required static routes are not configured, the following are the situations in which the communication works and when it does not:

  • Hosts in the Berlin network (192.0.2.0/24):

    • Can communicate with other hosts in the same subnet because they are directly connected.
    • Can communicate with the internet because Router 1 is in the Berlin network (192.0.2.0/24) and has a default gateway, which leads to the internet.
    • Can communicate with the data center network (203.0.113.0/24) because Router 1 has interfaces in both the Berlin (192.0.2.0/24) and the data center (203.0.113.0/24) networks.
    • Cannot communicate with the Raleigh network (198.51.100.0/24) because Router 1 has no interface in this network. Therefore, Router 1 sends the traffic to its own default gateway (internet).
  • Hosts in the data center network (203.0.113.0/24):

    • Can communicate with other hosts in the same subnet because they are directly connected.
    • Can communicate with the internet because they have their default gateway set to Router 1, and Router 1 has interfaces in both networks, the data center (203.0.113.0/24) and to the internet.
    • Can communicate with the Berlin network (192.0.2.0/24) because they have their default gateway set to Router 1, and Router 1 has interfaces in both the data center (203.0.113.0/24) and the Berlin (192.0.2.0/24) networks.
    • Cannot communicate with the Raleigh network (198.51.100.0/24) because the data center network has no interface in this network. Therefore, hosts in the data center (203.0.113.0/24) send traffic to their default gateway (Router 1). Router 1 also has no interface in the Raleigh network (198.51.100.0/24) and, as a result, Router 1 sends this traffic to its own default gateway (internet).
  • Hosts in the Raleigh network (198.51.100.0/24):

    • Can communicate with other hosts in the same subnet because they are directly connected.
    • Cannot communicate with hosts on the internet. Router 2 sends the traffic to Router 1 because of the default gateway settings. The actual behavior of Router 1 depends on the reverse path filter (rp_filter) system control (sysctl) setting. By default on RHEL, Router 1 drops the outgoing traffic instead of routing it to the internet. However, regardless of the configured behavior, communication is not possible without the static route.
    • Cannot communicate with the data center network (203.0.113.0/24). The outgoing traffic reaches the destination through Router 2 because of the default gateway setting. However, replies to packets do not reach the sender because hosts in the data center network (203.0.113.0/24) send replies to their default gateway (Router 1). Router 1 then sends the traffic to the internet.
    • Cannot communicate with the Berlin network (192.0.2.0/24). Router 2 sends the traffic to Router 1 because of the default gateway settings. The actual behavior of Router 1 depends on the sysctl setting rp_filter. By default on RHEL, Router 1 drops the outgoing traffic instead of sending it to the Berlin network (192.0.2.0/24). However, regardless of the configured behavior, communication is not possible without the static route.
Note

In addition to configuring the static routes, you must enable IP forwarding on both routers.

You can use the nmcli utility to configure a static route on the command line.

Use following syntax:

$ nmcli connection modify connection_name ipv4.routes "ip[/prefix] [next_hop] [metric] [attribute=value] [attribute=value] ..."
Copy to Clipboard Toggle word wrap

The command supports the following route attributes:

  • cwnd=n: Sets the congestion window (CWND) size, defined in the number of packets.
  • lock-cwnd=true|false: Defines whether or not the kernel can update the CWND value.
  • lock-mtu=true|false: Defines whether or not the kernel can update the MTU to path MTU discovery.
  • lock-window=true|false: Defines whether or not the kernel can update the maximum window size for TCP packets.
  • mtu=<mtu_value>: Sets the maximum transfer unit (MTU) to use along the path to the destination.
  • onlink=true|false: Defines whether the next hop is directly attached to this link even if it does not match any interface prefix.
  • scope=<scope>: For an IPv4 route, this attribute sets the scope of the destinations covered by the route prefix. Set the value as an integer (0-255).
  • src=<source_address>: Sets the source address to prefer when sending traffic to the destinations covered by the route prefix.
  • table=<table_id>: Sets the ID of the table the route should be added to. If you omit this parameter, NetworkManager uses the main table.
  • tos=<type_of_service_key>: Sets the type of service (TOS) key. Set the value as an integer (0-255).
  • type=<route_type>: Sets the route type. NetworkManager supports the unicast, local, blackhole, unreachable, prohibit, and throw route types. The default is unicast.
  • window=<window_size>: Sets the maximal window size for TCP to advertise to these destinations, measured in bytes.
Important

If you use the ipv4.routes option without a preceding + sign, nmcli overrides all current settings of this parameter.

  • To create an additional route, enter:

    $ nmcli connection modify connection_name +ipv4.routes "<route>"
    Copy to Clipboard Toggle word wrap
  • To remove a specific route, enter:

    $ nmcli connection modify connection_name -ipv4.routes "<route>"
    Copy to Clipboard Toggle word wrap

27.3. Configuring a static route by using nmcli

You can add a static route to an existing NetworkManager connection profile using the nmcli connection modify command.

The procedure below configures the following routes:

  • An IPv4 route to the remote 198.51.100.0/24 network. The corresponding gateway with the IP address 192.0.2.10 is reachable through the LAN connection profile.
  • An IPv6 route to the remote 2001:db8:2::/64 network. The corresponding gateway with the IP address 2001:db8:1::10 is reachable through the LAN connection profile.

Prerequisites

  • The LAN connection profile exists and it configures this host to be in the same IP subnet as the gateways.

Procedure

  1. Add the static IPv4 route to the LAN connection profile:

    # nmcli connection modify LAN +ipv4.routes "198.51.100.0/24 192.0.2.10"
    Copy to Clipboard Toggle word wrap

    To set multiple routes in one step, pass the individual routes comma-separated to the command:

    # nmcli connection modify <connection_profile> +ipv4.routes "<remote_network_1>/<subnet_mask_1> <gateway_1>, <remote_network_n>/<subnet_mask_n> <gateway_n>, ..."
    Copy to Clipboard Toggle word wrap
  2. Add the static IPv6 route to the LAN connection profile:

    # nmcli connection modify LAN +ipv6.routes "2001:db8:2::/64 2001:db8:1::10"
    Copy to Clipboard Toggle word wrap
  3. Re-activate the connection:

    # nmcli connection up LAN
    Copy to Clipboard Toggle word wrap

Verification

  1. Display the IPv4 routes:

    # ip -4 route
    ...
    198.51.100.0/24 via 192.0.2.10 dev enp1s0
    Copy to Clipboard Toggle word wrap
  2. Display the IPv6 routes:

    # ip -6 route
    ...
    2001:db8:2::/64 via 2001:db8:1::10 dev enp1s0 metric 1024 pref medium
    Copy to Clipboard Toggle word wrap

27.4. Configuring a static route by using nmtui

The nmtui application provides a text-based user interface for NetworkManager. You can use nmtui to configure static routes on a host without a graphical interface.

For example, the procedure below adds a route to the 192.0.2.0/24 network that uses the gateway running on 198.51.100.1, which is reachable through an existing connection profile.

Note

In nmtui:

  • Navigate by using the cursor keys.
  • Press a button by selecting it and hitting Enter.
  • Select and clear checkboxes by using Space.
  • To return to the previous screen, use ESC.

Prerequisites

  • The network is configured.
  • The gateway for the static route must be directly reachable on the interface.
  • If the user is logged in on a physical console, user permissions are sufficient. Otherwise, the command requires root permissions.

Procedure

  1. Start nmtui:

    # nmtui
    Copy to Clipboard Toggle word wrap
  2. Select Edit a connection, and press Enter.
  3. Select the connection profile through which you can reach the next hop to the destination network, and press Enter.
  4. Depending on whether it is an IPv4 or IPv6 route, press the Show button next to the protocol’s configuration area.
  5. Press the Edit button next to Routing. This opens a new window where you configure static routes:

    1. Press the Add button and fill in:

      • The destination network, including the prefix in Classless Inter-Domain Routing (CIDR) format
      • The IP address of the next hop
      • A metric value, if you add multiple routes to the same network and want to prioritize the routes by efficiency
    2. Repeat the previous step for every route you want to add and that is reachable through this connection profile.
    3. Press the OK button to return to the window with the connection settings.

      Figure 27.1. Example of a static route without metric

  6. Press the OK button to return to the nmtui main menu.
  7. Select Activate a connection and press Enter.
  8. Select the connection profile that you edited, and press Enter twice to deactivate and activate it again.

    Important

    Skip this step if you run nmtui over a remote connection, such as SSH, that uses the connection profile you want to reactivate. In this case, if you deactivate it in nmtui, the connection is terminated and, consequently, you cannot activate it again. To avoid this problem, use the nmcli connection <connection_profile> up command to reactivate the connection in the mentioned scenario.

  9. Press the Back button to return to the main menu.
  10. Select Quit, and press Enter to close the nmtui application.

Verification

  • Verify that the route is active:

    $ ip route
    ...
    192.0.2.0/24 via 198.51.100.1 dev example proto static metric 100
    Copy to Clipboard Toggle word wrap

You can use control-center in GNOME to add a static route to the configuration of a network connection.

The procedure below configures the following routes:

  • An IPv4 route to the remote 198.51.100.0/24 network. The corresponding gateway has the IP address 192.0.2.10.
  • An IPv6 route to the remote 2001:db8:2::/64 network. The corresponding gateway has the IP address 2001:db8:1::10.

Prerequisites

Procedure

  1. On the IPv4 tab:

    1. Optional: Disable automatic routes by clicking the On button in the Routes section of the IPv4 tab to use only static routes. If automatic routes are enabled, Red Hat Enterprise Linux uses static routes and routes received from a DHCP server.
    2. Enter the address, netmask, gateway, and optionally a metric value of the IPv4 route:

      IPv4 static route in control center

  2. On the IPv6 tab:

    1. Optional: Disable automatic routes by clicking the On button i the Routes section of the IPv4 tab to use only static routes.
    2. Enter the address, netmask, gateway, and optionally a metric value of the IPv6 route:

      IPv6 static route in control center

  3. Click Apply.
  4. Back in the Network window, disable and re-enable the connection by switching the button for the connection to Off and back to On for changes to take effect.

    Warning

    Restarting the connection briefly disrupts connectivity on that interface.

Verification

  1. Display the IPv4 routes:

    # ip -4 route
    ...
    198.51.100.0/24 via 192.0.2.10 dev enp1s0
    Copy to Clipboard Toggle word wrap
  2. Display the IPv6 routes:

    # ip -6 route
    ...
    2001:db8:2::/64 via 2001:db8:1::10 dev enp1s0 metric 1024 pref medium
    Copy to Clipboard Toggle word wrap

You can use the nm-connection-editor application to add a static route to the configuration of a network connection.

The procedure below configures the following routes:

  • An IPv4 route to the remote 198.51.100.0/24 network. The corresponding gateway with the IP address 192.0.2.10 is reachable through the example connection.
  • An IPv6 route to the remote 2001:db8:2::/64 network. The corresponding gateway with the IP address 2001:db8:1::10 is reachable through the example connection.

Prerequisites

  • The network is configured.
  • This host is in the same IP subnet as the gateways.

Procedure

  1. Open a terminal, and enter nm-connection-editor:

    $ nm-connection-editor
    Copy to Clipboard Toggle word wrap
  2. Select the example connection profile, and click the gear wheel icon to edit the existing connection.
  3. On the IPv4 Settings tab:

    1. Click the Routes button.
    2. Click the Add button and enter the address, netmask, gateway, and optionally a metric value.

      IPv4 static route in nm connection editor

    3. Click OK.
  4. On the IPv6 Settings tab:

    1. Click the Routes button.
    2. Click the Add button and enter the address, netmask, gateway, and optionally a metric value.

      IPv6 static route in nm connection editor

    3. Click OK.
  5. Click Save.
  6. Restart the network connection for changes to take effect. For example, to restart the example connection using the command line:

    # nmcli connection up example
    Copy to Clipboard Toggle word wrap

Verification

  1. Display the IPv4 routes:

    # ip -4 route
    ...
    198.51.100.0/24 via 192.0.2.10 dev enp1s0
    Copy to Clipboard Toggle word wrap
  2. Display the IPv6 routes:

    # ip -6 route
    ...
    2001:db8:2::/64 via 2001:db8:1::10 dev enp1s0 metric 1024 pref medium
    Copy to Clipboard Toggle word wrap

You can use the interactive mode of the nmcli utility to add a static route to the configuration of a network connection.

The procedure below configures the following routes:

  • An IPv4 route to the remote 198.51.100.0/24 network. The corresponding gateway with the IP address 192.0.2.10 is reachable through the example connection.
  • An IPv6 route to the remote 2001:db8:2::/64 network. The corresponding gateway with the IP address 2001:db8:1::10 is reachable through the example connection.

Prerequisites

  • The example connection profile exists and it configures this host to be in the same IP subnet as the gateways.

Procedure

  1. Open the nmcli interactive mode for the example connection:

    # nmcli connection edit example
    Copy to Clipboard Toggle word wrap
  2. Add the static IPv4 route:

    nmcli> set ipv4.routes 198.51.100.0/24 192.0.2.10
    Copy to Clipboard Toggle word wrap
  3. Add the static IPv6 route:

    nmcli> set ipv6.routes 2001:db8:2::/64 2001:db8:1::10
    Copy to Clipboard Toggle word wrap
  4. Optional: Verify that the routes were added correctly to the configuration:

    nmcli> print
    ...
    ipv4.routes:    { ip = 198.51.100.0/24, nh = 192.0.2.10 }
    ...
    ipv6.routes:    { ip = 2001:db8:2::/64, nh = 2001:db8:1::10 }
    ...
    Copy to Clipboard Toggle word wrap

    The ip attribute displays the network to route and the nh attribute the gateway (next hop).

  5. Save the configuration:

    nmcli> save persistent
    Copy to Clipboard Toggle word wrap
  6. Restart the network connection:

    nmcli> activate example
    Copy to Clipboard Toggle word wrap
  7. Leave the nmcli interactive mode:

    nmcli> quit
    Copy to Clipboard Toggle word wrap

Verification

  1. Display the IPv4 routes:

    # ip -4 route
    ...
    198.51.100.0/24 via 192.0.2.10 dev enp1s0
    Copy to Clipboard Toggle word wrap
  2. Display the IPv6 routes:

    # ip -6 route
    ...
    2001:db8:2::/64 via 2001:db8:1::10 dev enp1s0 metric 1024 pref medium
    Copy to Clipboard Toggle word wrap

You can use the declarative Nmstate API to configure a static route. Nmstate ensures that the result matches the configuration file or rolls back the changes.

Prerequisites

  • The enp1s0 network interface is configured and is in the same IP subnet as the gateways.
  • The nmstate package is installed.

Procedure

  1. Create a YAML file, for example ~/add-static-route-to-enp1s0.yml, with the following content:

    ---
    routes:
      config:
      - destination: 198.51.100.0/24
        next-hop-address: 192.0.2.10
        next-hop-interface: enp1s0
      - destination: 2001:db8:2::/64
        next-hop-address: 2001:db8:1::10
        next-hop-interface: enp1s0
    Copy to Clipboard Toggle word wrap

    These settings define the following static routes:

    • An IPv4 route to the remote 198.51.100.0/24 network. The corresponding gateway with the IP address 192.0.2.10 is reachable through the enp1s0 interface.
    • An IPv6 route to the remote 2001:db8:2::/64 network. The corresponding gateway with the IP address 2001:db8:1::10 is reachable through the enp1s0 interface.
  2. Apply the settings to the system:

    # nmstatectl apply ~/add-static-route-to-enp1s0.yml
    Copy to Clipboard Toggle word wrap

Verification

  1. Display the IPv4 routes:

    # ip -4 route
    ...
    198.51.100.0/24 via 192.0.2.10 dev enp1s0
    Copy to Clipboard Toggle word wrap
  2. Display the IPv6 routes:

    # ip -6 route
    ...
    2001:db8:2::/64 via 2001:db8:1::10 dev enp1s0 metric 1024 pref medium
    Copy to Clipboard Toggle word wrap

You can use the network RHEL system role to configure static routes.

Important

When you run a play that uses the network RHEL system role and if the setting values do not match the values specified in the play, the role overrides the existing connection profile with the same name. To prevent resetting these values to their defaults, always specify the whole configuration of the network connection profile in the play, even if the configuration, for example the IP configuration, already exists.

Prerequisites

Procedure

  1. Create a playbook file, for example, ~/playbook.yml, with the following content:

    ---
    - name: Configure the network
      hosts: managed-node-01.example.com
      tasks:
        - name: Ethernet connection profile with static IP address settings
          ansible.builtin.include_role:
            name: redhat.rhel_system_roles.network
          vars:
            network_connections:
              - name: enp7s0
                type: ethernet
                autoconnect: yes
                ip:
                  address:
                    - 192.0.2.1/24
                    - 2001:db8:1::1/64
                  gateway4: 192.0.2.254
                  gateway6: 2001:db8:1::fffe
                  dns:
                    - 192.0.2.200
                    - 2001:db8:1::ffbb
                  dns_search:
                    - example.com
                  route:
                    - network: 198.51.100.0
                      prefix: 24
                      gateway: 192.0.2.10
                    - network: '2001:db8:2::'
                      prefix: 64
                      gateway: 2001:db8:1::10
                state: up
    Copy to Clipboard Toggle word wrap

    For details about all variables used in the playbook, see the /usr/share/ansible/roles/rhel-system-roles.network/README.md file on the control node.

  2. Validate the playbook syntax:

    $ ansible-playbook --syntax-check ~/playbook.yml
    Copy to Clipboard Toggle word wrap

    Note that this command only validates the syntax and does not protect against a wrong but valid configuration.

  3. Run the playbook:

    $ ansible-playbook ~/playbook.yml
    Copy to Clipboard Toggle word wrap

Verification

  1. Display the IPv4 routes:

    # ansible managed-node-01.example.com -m command -a 'ip -4 route'
    managed-node-01.example.com | CHANGED | rc=0 >>
    ...
    198.51.100.0/24 via 192.0.2.10 dev enp7s0
    Copy to Clipboard Toggle word wrap
  2. Display the IPv6 routes:

    # ansible managed-node-01.example.com -m command -a 'ip -6 route'
    managed-node-01.example.com | CHANGED | rc=0 >>
    ...
    2001:db8:2::/64 via 2001:db8:1::10 dev enp7s0 metric 1024 pref medium
    Copy to Clipboard Toggle word wrap

By default, the RHEL kernel forwards network packets based on the destination address by using a routing table. With policy-based routing, you can configure complex scenarios to route packets based on various criteria, such as the source address.

You can use policy-based routing to configure a different default gateway for traffic from certain subnets.

For example, you can configure RHEL as a router that, by default, routes all traffic to internet provider A using the default route. However, traffic received from the internal workstations subnet is routed to provider B.

The procedure assumes the following network topology:

policy based routing

Prerequisites

  • The system uses NetworkManager to configure the network, which is the default.
  • The RHEL router you want to set up in the procedure has four network interfaces:

    • The enp7s0 interface is connected to the network of provider A. The gateway IP in the provider’s network is 198.51.100.2, and the network uses a /30 network mask.
    • The enp1s0 interface is connected to the network of provider B. The gateway IP in the provider’s network is 192.0.2.2, and the network uses a /30 network mask.
    • The enp8s0 interface is connected to the 10.0.0.0/24 subnet with internal workstations.
    • The enp9s0 interface is connected to the 203.0.113.0/24 subnet with the company’s servers.
  • Hosts in the internal workstations subnet use 10.0.0.1 as the default gateway. In the procedure, you assign this IP address to the enp8s0 network interface of the router.
  • Hosts in the server subnet use 203.0.113.1 as the default gateway. In the procedure, you assign this IP address to the enp9s0 network interface of the router.
  • The firewalld service is enabled and active.

Procedure

  1. Configure the network interface to provider A:

    # nmcli connection add type ethernet con-name Provider-A ifname enp7s0 ipv4.method manual ipv4.addresses 198.51.100.1/30 ipv4.gateway 198.51.100.2 ipv4.dns 198.51.100.200 connection.zone external
    Copy to Clipboard Toggle word wrap

    The nmcli connection add command creates a NetworkManager connection profile. The command uses the following options:

    • type ethernet: Defines that the connection type is Ethernet.
    • con-name <connection_name>: Sets the name of the profile. Use a meaningful name to avoid confusion.
    • ifname <network_device>: Sets the network interface.
    • ipv4.method manual: Enables to configure a static IP address.
    • ipv4.addresses <IP_address>/<subnet_mask>: Sets the IPv4 addresses and subnet mask.
    • ipv4.gateway <IP_address>: Sets the default gateway address.
    • ipv4.dns <IP_of_DNS_server>: Sets the IPv4 address of the DNS server.
    • connection.zone <firewalld_zone>: Assigns the network interface to the defined firewalld zone. Note that firewalld automatically enables masquerading for interfaces assigned to the external zone.
  2. Configure the network interface to provider B:

    # nmcli connection add type ethernet con-name Provider-B ifname enp1s0 ipv4.method manual ipv4.addresses 192.0.2.1/30 ipv4.routes "0.0.0.0/0 192.0.2.2 table=5000" connection.zone external
    Copy to Clipboard Toggle word wrap

    This command uses the ipv4.routes parameter instead of ipv4.gateway to set the default gateway. This is required to assign the default gateway for this connection to a different routing table (5000) than the default. NetworkManager automatically creates this new routing table when the connection is activated.

  3. Configure the network interface to the internal workstations subnet:

    # nmcli connection add type ethernet con-name Internal-Workstations ifname enp8s0 ipv4.method manual ipv4.addresses 10.0.0.1/24 ipv4.routes "10.0.0.0/24 table=5000" ipv4.routing-rules "priority 5 from 10.0.0.0/24 table 5000" connection.zone trusted
    Copy to Clipboard Toggle word wrap

    This command uses the ipv4.routes parameter to add a static route to the routing table with ID 5000. This static route for the 10.0.0.0/24 subnet uses the IP of the local network interface to provider B (192.0.2.1) as next hop.

    Additionally, the command uses the ipv4.routing-rules parameter to add a routing rule with priority 5 that routes traffic from the 10.0.0.0/24 subnet to table 5000. Low values have a high priority.

    Note that the syntax in the ipv4.routing-rules parameter is the same as in an ip rule add command, except that ipv4.routing-rules always requires specifying a priority.

  4. Configure the network interface to the server subnet:

    # nmcli connection add type ethernet con-name Servers ifname enp9s0 ipv4.method manual ipv4.addresses 203.0.113.1/24 connection.zone trusted
    Copy to Clipboard Toggle word wrap

Verification

  1. On a RHEL host in the internal workstation subnet:

    1. Install the traceroute package:

      # dnf install traceroute
      Copy to Clipboard Toggle word wrap
    2. Use the traceroute utility to display the route to a host on the internet:

      # traceroute redhat.com
      traceroute to redhat.com (209.132.183.105), 30 hops max, 60 byte packets
       1  10.0.0.1 (10.0.0.1)     0.337 ms  0.260 ms  0.223 ms
       2  192.0.2.2 (192.0.2.2)   0.884 ms  1.066 ms  1.248 ms
       ...
      Copy to Clipboard Toggle word wrap

      The output of the command displays that the router sends packets over 192.0.2.1, which is the network of provider B.

  2. On a RHEL host in the server subnet:

    1. Install the traceroute package:

      # dnf install traceroute
      Copy to Clipboard Toggle word wrap
    2. Use the traceroute utility to display the route to a host on the internet:

      # traceroute redhat.com
      traceroute to redhat.com (209.132.183.105), 30 hops max, 60 byte packets
       1  203.0.113.1 (203.0.113.1)    2.179 ms  2.073 ms  1.944 ms
       2  198.51.100.2 (198.51.100.2)  1.868 ms  1.798 ms  1.549 ms
       ...
      Copy to Clipboard Toggle word wrap

      The output of the command displays that the router sends packets over 198.51.100.2, which is the network of provider A.

Troubleshooting steps

On the RHEL router:

  1. Display the rule list:

    # ip rule list
    0:	from all lookup local
    5:	from 10.0.0.0/24 lookup 5000
    32766:	from all lookup main
    32767:	from all lookup default
    Copy to Clipboard Toggle word wrap

    By default, RHEL contains rules for the tables local, main, and default.

  2. Display the routes in table 5000:

    # ip route list table 5000
    0.0.0.0/0 via 192.0.2.2 dev enp1s0 proto static metric 100
    10.0.0.0/24 dev enp8s0 proto static scope link src 192.0.2.1 metric 102
    Copy to Clipboard Toggle word wrap
  3. Display the interfaces and firewall zones:

    # firewall-cmd --get-active-zones
    external
      interfaces: enp1s0 enp7s0
    trusted
      interfaces: enp8s0 enp9s0
    Copy to Clipboard Toggle word wrap
  4. Verify that the external zone has masquerading enabled:

    # firewall-cmd --info-zone=external
    external (active)
      target: default
      icmp-block-inversion: no
      interfaces: enp1s0 enp7s0
      sources:
      services: ssh
      ports:
      protocols:
      masquerade: yes
      ...
    Copy to Clipboard Toggle word wrap

You can use policy-based routing to configure a different default gateway for traffic from certain subnets. By using the network RHEL system role, you can automate the creation of the connection profiles, including routing tables and rules.

For example, you can configure RHEL as a router that, by default, routes all traffic to internet provider A using the default route. However, traffic received from the internal workstations subnet is routed to provider B. By using Ansible and the network RHEL system role, you can automate this process and remotely configure connection profiles on the hosts defined in a playbook.

This procedure assumes the following network topology:

policy based routing

Prerequisites

  • You have prepared the control node and the managed nodes.
  • You are logged in to the control node as a user who can run playbooks on the managed nodes.
  • The account you use to connect to the managed nodes has sudo permissions on them.
  • The managed nodes use NetworkManager and the firewalld service.
  • The managed nodes you want to configure has four network interfaces:

    • The enp7s0 interface is connected to the network of provider A. The gateway IP in the provider’s network is 198.51.100.2, and the network uses a /30 network mask.
    • The enp1s0 interface is connected to the network of provider B. The gateway IP in the provider’s network is 192.0.2.2, and the network uses a /30 network mask.
    • The enp8s0 interface is connected to the 10.0.0.0/24 subnet with internal workstations.
    • The enp9s0 interface is connected to the 203.0.113.0/24 subnet with the company’s servers.
  • Hosts in the internal workstations subnet use 10.0.0.1 as the default gateway. In the procedure, you assign this IP address to the enp8s0 network interface of the router.
  • Hosts in the server subnet use 203.0.113.1 as the default gateway. In the procedure, you assign this IP address to the enp9s0 network interface of the router.

Procedure

  1. Create a playbook file, for example, ~/playbook.yml, with the following content:

    ---
    - name: Configuring policy-based routing
      hosts: managed-node-01.example.com
      tasks:
        - name: Routing traffic from a specific subnet to a different default gateway
          ansible.builtin.include_role:
            name: redhat.rhel_system_roles.network
          vars:
            network_connections:
              - name: Provider-A
                interface_name: enp7s0
                type: ethernet
                autoconnect: True
                ip:
                  address:
                    - 198.51.100.1/30
                  gateway4: 198.51.100.2
                  dns:
                    - 198.51.100.200
                state: up
                zone: external
    
              - name: Provider-B
                interface_name: enp1s0
                type: ethernet
                autoconnect: True
                ip:
                  address:
                    - 192.0.2.1/30
                  route:
                    - network: 0.0.0.0
                      prefix: 0
                      gateway: 192.0.2.2
                      table: 5000
                state: up
                zone: external
    
              - name: Internal-Workstations
                interface_name: enp8s0
                type: ethernet
                autoconnect: True
                ip:
                  address:
                    - 10.0.0.1/24
                  route:
                    - network: 10.0.0.0
                      prefix: 24
                      table: 5000
                  routing_rule:
                    - priority: 5
                      from: 10.0.0.0/24
                      table: 5000
                state: up
                zone: trusted
    
              - name: Servers
                interface_name: enp9s0
                type: ethernet
                autoconnect: True
                ip:
                  address:
                    - 203.0.113.1/24
                state: up
                zone: trusted
    Copy to Clipboard Toggle word wrap

    The settings specified in the example playbook include the following:

    table: <value>
    Assigns the route from the same list entry as the table variable to the specified routing table.
    routing_rule: <list>
    Defines the priority of the specified routing rule and from a connection profile to which routing table the rule is assigned.
    zone: <zone_name>
    Assigns the network interface from a connection profile to the specified firewalld zone.

    For details about all variables used in the playbook, see the /usr/share/ansible/roles/rhel-system-roles.network/README.md file on the control node.

  2. Validate the playbook syntax:

    $ ansible-playbook --syntax-check ~/playbook.yml
    Copy to Clipboard Toggle word wrap

    Note that this command only validates the syntax and does not protect against a wrong but valid configuration.

  3. Run the playbook:

    $ ansible-playbook ~/playbook.yml
    Copy to Clipboard Toggle word wrap

Verification

  1. On a RHEL host in the internal workstation subnet:

    1. Install the traceroute package:

      # dnf install traceroute
      Copy to Clipboard Toggle word wrap
    2. Use the traceroute utility to display the route to a host on the internet:

      # traceroute redhat.com
      traceroute to redhat.com (209.132.183.105), 30 hops max, 60 byte packets
       1  10.0.0.1 (10.0.0.1)     0.337 ms  0.260 ms  0.223 ms
       2  192.0.2.2 (192.0.2.2)   0.884 ms  1.066 ms  1.248 ms
       ...
      Copy to Clipboard Toggle word wrap

      The output of the command displays that the router sends packets over 192.0.2.1, which is the network of provider B.

  2. On a RHEL host in the server subnet:

    1. Install the traceroute package:

      # dnf install traceroute
      Copy to Clipboard Toggle word wrap
    2. Use the traceroute utility to display the route to a host on the internet:

      # traceroute redhat.com
      traceroute to redhat.com (209.132.183.105), 30 hops max, 60 byte packets
       1  203.0.113.1 (203.0.113.1)    2.179 ms  2.073 ms  1.944 ms
       2  198.51.100.2 (198.51.100.2)  1.868 ms  1.798 ms  1.549 ms
       ...
      Copy to Clipboard Toggle word wrap

      The output of the command displays that the router sends packets over 198.51.100.2, which is the network of provider A.

  3. On the RHEL router that you configured using the RHEL system role:

    1. Display the rule list:

      # ip rule list
      0:      from all lookup local
      5:    from 10.0.0.0/24 lookup 5000
      32766:  from all lookup main
      32767:  from all lookup default
      Copy to Clipboard Toggle word wrap

      By default, RHEL contains rules for the tables local, main, and default.

    2. Display the routes in table 5000:

      # ip route list table 5000
      0.0.0.0/0 via 192.0.2.2 dev enp1s0 proto static metric 100
      10.0.0.0/24 dev enp8s0 proto static scope link src 192.0.2.1 metric 102
      Copy to Clipboard Toggle word wrap
    3. Display the interfaces and firewall zones:

      # firewall-cmd --get-active-zones
      external
        interfaces: enp1s0 enp7s0
      trusted
        interfaces: enp8s0 enp9s0
      Copy to Clipboard Toggle word wrap
    4. Verify that the external zone has masquerading enabled:

      # firewall-cmd --info-zone=external
      external (active)
        target: default
        icmp-block-inversion: no
        interfaces: enp1s0 enp7s0
        sources:
        services: ssh
        ports:
        protocols:
        masquerade: yes
        ...
      Copy to Clipboard Toggle word wrap
Back to top
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Theme

© 2025 Red Hat