Policy-Based Routing (PBR)

About

This document aims to provide some example use cases and example scenarios how Policy-Based Routing (PBR) could be utilized to solve specific routing situations.

Introduction

Utilization of PBR allows an operator to configure routing setups that can perform decisions on additional criteria, rather than it just being based on the destination address, as with regular routes. This can allow for more agile routing solutions and a toolkit to solve specific situations.

The examples presented in this document are intended to provide ideas and inspiration as to how PBR can be applied and utilized, not necessarily general solutions applicable in every situation.

Case 1: Source-Based Routing

In regular routing the next hop is decided based on the destination IP address of a specific frame. However, situations may arise where it could be beneficial to base routing decisions on the source IP instead, performing source-based routing. There exist several reasons why this could be beneficial in different situations, here are just a few examples:

  • Having specific ISPs handle frames from a select group of hosts
  • Load-balancing of traffic towards different ISPs
  • Prioritize traffic originating from specific hosts on higher-bandwidth links

In this use case scenario, policy-base routing will be utilized in order to direct traffic from different hosts towards different ISPs depending on their source IP, resulting in source-based routing.

Tip

It is possible to configure a policy-based route to perform source-based routing only for specific destination addresses. This can be done by combining the various match options when configuring the PBR instance, see this for all match options.

                      .--.-.
                     ( (    )__
                    (_,  \ ) ,_)  Internet
                      '-'--`--'
                       |     |
                       |     |
               .-------'     '-------.
               |                     |
               |                     |
          .----+----.           .----+----.
          |         |           |         |
          |  ISP1   |           |  ISP2   |
          |         |           |         |
          '----+----'           '----+----'
           .99 |                     | .99
               |                     |
 172.16.1.0/24 '-------.     .-------' 172.16.2.0/24
                       |     |
                    .1 |     | .1
                     .-+-----+-.
                     |         |
                     |   R1    |
                     |         |
                     '----+----'
                          | vlan1
                          |
                          |
                     .----+----.
 192.168.1.0/24      |         |      192.168.2.0/24
  .------+------+----+ Switch  +----+------+------.
  |      |      |    |         |    |      |      |
  |      |      |    '---------'    |      |      |
  |      |      |                   |      |      |
.-+--. .-+--. .-+--.             .--+-. .--+-. .--+-.
| H1 | | H2 | | H3 |             | H4 | | H5 | | H6 |
'----' '----' '----'             '----' '----' '----'

Figure 1: Example of a setup with two different ISPs connected to the router R1. In addition, R1 is also connected to a switch with a number of hosts connected on two different VLANs.

The example topology presented in Figure 1, show a setup that have two different ISPs ISP1 and ISP2 that are both connected to the router R1, on the networks 172.16.1.0/24 and 172.16.2.0/24 respectively. Also connected to R1 is a switch with a number of different hosts connected to it.

The main focus for this HowTo will be the configuration of router R1. The intent is to configure it so that any traffic originating from the network 192.168.1.0/24 is routed towards ISP1 and any traffic originating from 192.168.2.0/24 is routed towards ISP2.

When this has been configured it should result in traffic originating from the hosts H1, H2 and H3 to be routed through ISP1. Similarly, the hosts H4, H5 and H6 should be routed through ISP2.

Configuration

The policy-based routes are configured on router R1. We assume that all the interfaces have already been configured in a suitable manner. The important thing for the sake of the example, is that vlan1 have been configured as the interface connected to the downstream switch.

First we configure the policy-based route responsible for routing the frames with a source within 192.168.1.0/24 towards ISP1 located at 172.16.1.99:

R1:/#> configure
R1:/config/#> ip
R1:/config/ip/#> policy-route 1
R1:/config/ip/policy-route-1/#> match saddr 192.168.1.0/24
R1:/config/ip/policy-route-1/#> in-iface vlan1
R1:/config/ip/policy-route-1/#> next-hop 172.16.1.99
R1:/config/ip/policy-route-1/#> end
R1:/config/ip/#>

Next we configure the second policy route, responsible for handling routing of frames with sources within 192.168.2.0/24 towards ISP2 located at 172.16.2.99:

R1:/config/ip/#> policy-route 2
R1:/config/ip/policy-route-2/#> match saddr 192.168.2.0/24
R1:/config/ip/policy-route-2/#> in-iface vlan1
R1:/config/ip/policy-route-2/#> next-hop 172.16.2.99
R1:/config/ip/policy-route-2/#> end
R1:/config/ip/#>

If we check the overall policy routing configuration it should now look something like the following:

R1:/config/ip/#> show policy-route
ID   ENA  PREF  IN-IFACES   MATCH     VALUE                 NEXT-HOP          
1    Yes  Auto  vlan1       saddr:    192.168.1.0/24        172.16.1.99
2    Yes  Auto  vlan1       saddr:    192.168.2.0/24        172.16.2.99

If everything looks like expected, leave the configuration context to apply to configuration:

R1:/config/ip/#> leave
Applying configuration.
Configuration activated.  Remember "copy run start" to save to flash (NVRAM).
R1:/#>

Status

When the policy routes have been configured they should be observable using the following command:

R1:/#> show ip policy-route
PRIO  SADDR           DADDR  SPORT  DPORT  IN-IFACE  NEXT-HOP   
300   192.168.1.0/24  -      -      -      vlan1     172.16.1.99
301   192.168.2.0/24  -      -      -      vlan1     172.16.2.99

If the NEXT-HOP is reports Unreachable the link towards the next-hop may be down. It could also be the case that the network have not been configured correctly, since if there is no network in the same subnet as the next hop, the route will not be active.

Note

The status of the policy routes should be viewed using the show ip policy-route command, they will not be presented when using the regular show ip route command.

Case 2: Protocol-Based Routing

Imagine in this specific scenario that we want to route all WEB related traffic in direction towards a particular ISP, while all the other traffic is routed to another. We can achieve this by utilizing PBR and perform matching on the port numbers used by the protocols.

                           .--.-.
                          ( (    )__
                         (_,  \ ) ,_)  Internet
                           '-'--`--'
                            |     |
                            |     |
                    .-------'     '-------.
           .-->     |                     |     <--.
           |        |                     |        |
   Other   |   .----+----.           .----+----.   | HTTP/HTTPS
   Traffic |   |         |           |         |   | Traffic
           |   |  ISP1   |           |  ISP2   |   |
           |   |         |           |         |   |
           |   '----+----'           '----+----'   |
                .99 |                     | .99
                    |                     |
      172.16.1.0/24 '-------.     .-------' 172.16.2.0/24
                            |     |
                         .1 |     | .1
                          .-+-----+-.
                          |         |
                          |   R1    |
                          |         |
                          '----+----'
                               | vlan1
                               |
                               |
                           .--.-.
                          ( (    )__
                         (_,  \ ) ,_)  LAN
                           '-'--`--'

Figure 2: Example of a setup with two different ISPs connected to the router R1. Where R1 is configured to send all the HTTP/HTTPS request traffic towards ISP2 and the rest towards ISP1.

The example scenario presented in Figure 2 shows two different ISPs, ISP1 and ISP2, connected to the router R1. The goal is that we want any HTTP and HTTPS traffic originating from the LAN network to be routed towards ISP2, located on next hop 172.16.2.99. Any other traffic from the LAN should be sent towards ISP1 located at the next hop 172.16.1.99.

To achieve this desired behavior a regular default gateway is configured on R1 directing traffic towards ISP1. Afterwards, a policy-based route is configured on R1 that matches on the destination ports, 80 for HTTP and 443 for HTTPS, with ISP2 as the next hop address located at 172.16.2.99.

This specific example focuses on requests originating somewhere on the LAN, for a web server located somewhere on the internet.

Note

Configuring the PBR in this way would only enforce outgoing traffic, as in trying to access a WEB page from the LAN located on the internet, since we are matching on the destination port.

Say we would want to access a web server on the LAN from the internet, but retain the same routing, we would also need to add a similar rule that matches on source port instead of destination.

Configuration

The policy-based routes are configured on router R1. We assume that all the interfaces have already been configured in a suitable manner.

First we configure a regular default route towards ISP1 that should handle all the other traffic:

R1:/#> configure
R1:/config/#> ip
R1:/config/ip/#> route default 172.16.1.99
R1:/config/ip/#>

Now we can configure the policy-based routes. In this case we will need to configure two separate instances, one to handle HTTP (port 80), and another to handle HTTPS (port 443). We start with the configuration of the HTTP matching route:

R1:/config/ip/#> policy-route 1
R1:/config/ip/policy-route-1/#> match dport 80
R1:/config/ip/policy-route-1/#> in-iface vlan1
R1:/config/ip/policy-route-1/#> next-hop 172.16.2.99
R1:/config/ip/policy-route-1/#> end
R1:/config/ip/#>

Now we configure a second policy-based route instance for covering HTTPS traffic:

R1:/config/ip/#> policy-route 2
R1:/config/ip/policy-route-2/#> match dport 443
R1:/config/ip/policy-route-2/#> in-iface vlan1
R1:/config/ip/policy-route-2/#> next-hop 172.16.2.99
R1:/config/ip/policy-route-2/#> end
R1:/config/ip/#>

The configuration should now look something like this:

R1:/config/ip/#> show policy-route
ID   ENA  PREF  IN-IFACES   MATCH     VALUE                 NEXT-HOP          
1    Yes  Auto  vlan1       dport:    80                    172.16.2.99
2    Yes  Auto  vlan1       dport:    443                   172.16.2.99
R1:/config/ip/#>

If everything looks okay we can leave the configuration context, in order to apply the configuration:

R1:/config/ip/#> leave
Applying configuration.
Configuration activated.  Remember "copy run start" to save to flash (NVRAM).
R1:/#>

Status

If everything has been set up correctly, the policy routes should now be active on the device:

R1:/#> show ip policy-route
PRIO  SADDR  DADDR  SPORT  DPORT  IN-IFACE  NEXT-HOP   
300   -      -      -      80     vlan1     172.16.2.99
301   -      -      -      443    vlan1     172.16.2.99

If the NEXT-HOP reports Unreachable, the link towards the next-hop may be down. It could also be the case that the network have not been configured correctly, since if there is no network in the same subnet as the next hop, the route will not be active.

Case 3: Locally Originated Traffic

The scenario presented in this case serve to provide an example how a policy route can be setup to apply only on frames originating from the device itself, essentially direct access to the router itself.

           .---------.                      .---------.
           |         |     172.16.1.0/24    |         |
           |   R1    +----------------------+   R2    |
           |         | .10              .20 |         |
           '----+----'                      '----+----'
                | .10                        .20 |
192.168.10.0/24 |                                | 192.168.20.0/24
                | .1                          .2 |
              .-+--.                           .-+--.
              | H1 |                           | H2 |
              '----'                           '----'

         GW: 192.168.10.10               GW: 192.168.20.20

Figure 3: Basic setup with two routers and two hosts.

Based on the topology presented in Figure 3, imagine that we for some reason would like both hosts to be able to reach both of the routers, but not each other. In order to achieve this we could use a simple policy-based route configuration, one on each of the routers.

However, first it is good to note why we may not be able to achieve this behavior using regular static routes. For instance, if we want H1 to be able to reach R2 using regular static routes, we could configure 172.16.1.10 as the next hop for 192.168.10.0/24 on R2. Doing this would ensure that we could reach the net of host H1 from R2.

In addition, we also want H2 to be able to reach R1, so we add corresponding routes on R1, with 172.16.1.20 being the next hop for 192.168.20.0/24.

At this point we would be able to reach R2 from H1 and correspondingly, R1 from H2. However, the two hosts would also be able to reach each other, but we only wanted them to be able to reach the routers themselves.

Now, instead of adding static routes we want to configure policy-based routes on each of the routers, in a way that only allow the route to be utilized for traffic originating from the router itself. It will be setup so that H2 can reach R1 on 172.16.1.10 and so that H1 can reach R2 on 172.16.1.20.

Configuration

Each of the two routers, R1 and R2, needs to be configured with a policy route each. We also assume for this scenario that all the relevant interfaces have already been configured.

Each of the policy routes are intended to be usable for frames originating from the device itself. This can be achieved by specifying the interface lo as the in-iface for the policy route. In addition, the match rule itself will be configured to be the saddr of the device itself. So for R1 the saddr will be set to 172.16.1.10 and for R2 it will be set to 172.16.1.20.

R1

The policy-based route instance is configured on the device in the following manner:

R1:/#> configure
R1:/config/#> ip
R1:/config/ip/#> policy-route 1
R1:/config/ip/policy-route-1/#> match saddr 172.16.1.10
R1:/config/ip/policy-route-1/#> in-iface lo
R1:/config/ip/policy-route-1/#> next-hop 172.16.1.20
R1:/config/ip/policy-route-1/#> end
R1:/config/ip/#> leave
Applying configuration.
Configuration activated.  Remember "copy run start" to save to flash (NVRAM).
R1:/#>

This policy-based route will ensure that any traffic directed towards R1 on 172.16.1.10, will have the response routed towards 172.16.1.20.

R2

The policy-based route instance is configured on the device in the following manner:

R2:/#> configure
R2:/config/#> ip
R2:/config/ip/#> policy-route 1
R2:/config/ip/policy-route-1/#> match saddr 172.16.1.20
R2:/config/ip/policy-route-1/#> in-iface lo
R2:/config/ip/policy-route-1/#> next-hop 172.16.1.10
R2:/config/ip/policy-route-1/#> end
R2:/config/ip/#> leave
Applying configuration.
Configuration activated.  Remember "copy run start" to save to flash (NVRAM).
R2:/#>

This policy-based route will ensure that any traffic directed towards R2 on 172.16.1.20, will have the response routed towards 172.16.1.10.

Status

If both the routers have been configured correctly, the active policy-based routes should look something like this, starting with R1:

R1:/#> show ip policy-route
PRIO  SADDR           DADDR  SPORT  DPORT  IN-IFACE  NEXT-HOP   
300   172.16.1.10/32  -      -      -      lo        172.16.1.20

For R2 it should look something like this:

R2:/#> show ip policy-route
PRIO  SADDR           DADDR  SPORT  DPORT  IN-IFACE  NEXT-HOP   
300   172.16.1.20/32  -      -      -      lo        172.16.1.10

Verify the Behavior

At this point it should be possible for H1 to reach R2 on 172.16.1.20. We can test this by simply using ping:

H1:/#> ping count 3 172.16.1.20
Press Ctrl-C to abort PING 172.16.1.20 (172.16.1.20): 56 data bytes
64 bytes from 172.16.1.20: seq=0 ttl=63 time=3.379 ms
64 bytes from 172.16.1.20: seq=1 ttl=63 time=3.731 ms
64 bytes from 172.16.1.20: seq=2 ttl=63 time=3.655 ms

--- 172.16.1.20 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 3.379/3.588/3.731 ms
H1:/#>

However, we should not be able to reach anything in the 192.168.20.0/24 subnet, this includes R2 on that address and H2:

H1:/#> ping count 3 192.168.20.20
Press Ctrl-C to abort PING 192.168.20.20 (192.168.20.20): 56 data bytes

--- 192.168.20.20 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss
H1:/#>
H1:/#> ping count 3 192.168.20.2
Press Ctrl-C to abort PING 192.168.20.2 (192.168.20.2): 56 data bytes

--- 192.168.20.2 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss
H1:/#>

The same verification could be done from H1, checking that R1 on 172.16.1.10.