Previous section   Next section

Recipe 5.6 Using Policy-Based Routing to Route Based on Source Address

5.6.1 Problem

You want to use different network links depending on the source address.

5.6.2 Solution

Policy-based routing allows you to configure special routing rules beyond the normal IP routing table. One common application is to route packets based on the IP source address, rather than (or in addition to) using the destination address:

Router#configure terminal
Enter configuration commands, one per line.  End with CNTL/Z.
Router(config)#access-list 1 permit 10.15.35.0 0.0.0.255
Router(config)#access-list 2 permit 10.15.36.0 0.0.0.255
Router(config)#interface Ethernet0
Router(config-if)#ip address 10.15.22.7 255.255.255.0
Router(config-if)#ip policy route-map Engineers
Router(config-if)#ip route-cache policy
Router(config-if)#exit
Router(config)#route-map Engineers permit 10
Router(config-route-map)#match ip address 1
Router(config-route-map)#set ip next-hop 10.15.27.1
Router(config-route-map)#exit
Router(config)#route-map Engineers permit 20
Router(config-route-map)#match ip address 2
Router(config-route-map)#set interface Ethernet1
Router(config-route-map)#end
Router#

5.6.3 Discussion

This configuration example defines a special routing policy for a group of users defined by the route map called "Engineers." This name is arbitrary, and we recommend that you choose names for your route maps that are meaningful in your organization. This example applies the route map called "Engineers" to all of the packets received on the interface Ethernet0. This configuration might be required because certain users need to use a special higher capacity link, for example.

There are two clauses in this route map. The numbers "10" and "20" at the end of each of the route-map command lines are used to specify the order in which the router will apply these clauses when making routing decisions. It is a good practice to use widely spaced numbers like this—it makes it easier to insert new clauses between them. For example, if we needed to add a new clause that had to be executed after the first one but before the last one, we could give it a value of 15.

It is also important to remember that every route map ends with an implicit deny all. This ensures that packets that don't match either of the clauses in this route map are unaffected, and will use the standard IP routing table.

The permit field is somewhat confusing in general because it governs whether the route-map clause will permit or deny the set operation contained below it. There are very few cases where the deny option is used in practice.

The first route-map clause takes action based on the match command:

Router(config)#route-map Engineers permit 10
Router(config-route-map)#match ip address 1
Router(config-route-map)#set ip next-hop 10.15.27.1
Router(config-route-map)#exit

This command compares the contents of the IP header with access list number 1. Note that this is a standard access list, which is used only to match the source address in the IP header. You can also use extended access lists to match any of the header contents. With extended access lists, you can even match TCP or UDP port numbers. The term address in the route-map match clause is slightly misleading when extended access lists are used because you can actually match just about anything in the IP header. In this case, however, we are looking for an address.

Access list 1 will match any packet with a source address in the range from 10.15.35.0 to 10.15.35.255:

Router(config)#access-list 1 permit 10.15.35.0 0.0.0.255

If the match is successful, the route map will apply the set command, which overrides any routing table information and sends the packet to the next-hop router, 10.15.27.1. Note that this next-hop router must be on a directly connected network because the router will bypass its routing table when it forwards these packets. If the next-hop address is not part of a directly connected subnet, the router can't route the packet because it has already bypassed the routing table in its decision process.

The second clause works in a similar way, but it matches a different access list and sets a different next-hop value:

Router(config)#route-map Engineers permit 20
Router(config-route-map)#match ip address 2
Router(config-route-map)#set interface Ethernet1

This clause also handles the routing differently. Instead of specifying a next hop, it specifies that any packets matching this rule will be forwarded directly out of the Ethernet1 interface. This requires that either the destination device must be on this segment, or a router configured with proxy ARP is available to forward the packet to the ultimate destination.

Because the route map ends with an implicit deny all, all packets that don't match any clause are routed in the normal way using information in the routing table.

You can use the set next-hop command to set a series of possible next hops:

Router(config-route-map)#set ip next-hop 10.15.27.1 10.15.37.1

You can also specify several different possible interfaces:

Router(config-route-map)#set interface Ethernet1 Ethernet2

This allows you to define what happens if there is no way to route to one of these next-hop devices. If the first address or interface is not available, the router will use the second.

The router will consult its routing table to decide whether the specified next-hop router or interface is available. This is important because, in many cases (such as when using Ethernet segments), it is possible to lose contact with the next-hop router without losing the routing table entry. In this case, the packet will simply be dropped.

In IOS Version 12.0(3)T and later, there is a partial solution to this problem. You can specify the set ip next-hop verify-availability command to make the router use CDP to test whether the next-hop device is up:

Router(config)#route-map Engineers permit 10
Router(config-route-map)#match ip address 1
Router(config-route-map)#set ip next-hop 10.15.27.1 
Router(config-route-map)#set ip next-hop verify-availability

Since this uses CDP, you have to ensure that CDP is enabled on the interface leading to this next-hop device. That device must also be running CDP (meaning it must be another Cisco router). This is not a perfect solution because not all media types support CDP, and because the verification process can cause performance problems. Furthermore, CDP uses a relatively long timeout period by default (180 seconds), so it is slow to respond to failures.

If none of the next hops are available, the router simply uses its normal routing table. If the routing table does not have an entry for this route, you may want to specify a default other than the router's general default gateway:

Router(config)#route-map Engineers permit 10
Router(config-route-map)#set ip default next-hop 10.15.47.1

You can also specify a default interface in a similar way:

Router(config)#route-map Engineers permit 10
Router(config-route-map)#set default interface Null0

In this case, the default interface is the Null0 interface. Setting this forces the router to discard the packets rather than using the router's general default gateway.

There is one other extremely important command in the main recipe example, ip route-cache policy:

Router(config)#interface Ethernet0
Router(config-if)#ip route-cache policy

This command tells the router to use fast switching rather than process switching when processing policy commands on the specified interface. This command is new in IOS Version 12.0. Without it, all policy processing is handled by the router's CPU. This can cause serious performance problems in a slower router, or if the traffic load is heavy.

Note, however, that not all policy-based routing commands can be fast switched. In particular, the set ip default next-hop and set default interface commands are not supported. Furthermore, fast switching has only limited support for the set interface command. In particular, the destination interface must have route caching enabled, or it must be a point-to-point link. And, even if these conditions are true, the router still must check its routing table at the process level to ensure that the destination interface is valid. Recipe 5.7 discusses these commands.

Because policy-based routing overrides the normal routing tables within the router, using it can result in some interesting and confusing troubleshooting problems. In the above example, if the next-hop value 10.15.27.1 suffers a failure but its subnet doesn't drop out of the routing table, no dynamic routing protocol is available to find a new path. Worse still, trying to diagnose the problem using normal procedures (such as trying to ping from the router to the required destination) will give unpredictable results because the ICMP packets originating on the router will not be subject to the routing policy. You may find that you can ping, but that the application doesn't work for certain users.

For this reason, we recommend avoiding policy-based routing unless there is no other way to accomplish the required goals.

5.6.4 See Also

Recipe 5.7


  Previous section   Next section
Top