Policy-based routing for IP networks in Cisco routers is a very powerful and precise tool which allows a network administrator to achieve a great many things. In my opinion it should be considered just as fundamental, as general routing mechanisms. How it is different from general destination-based routing and what we can to with it is the subject of today’s post.
Policy-based routing overview
So, in my post on general IP routing, I’ve described routing process as taking a function of the packet (of the packet’s IP header, to be precise) and using it to determine the packet’s next “hop”. There, I described that the routing table is the notation in which such a function is described. The downside of it is that with a fixed-format table one can only describe a fixed format function in the form of “if DESTADDR $\in$ NETWORK then NEXTHOP”. Most of the times, such format, called Destination-based routing, is just enough.
But what if we wanted to write a somewhat arbitrary function into this blackbox? And result it not only in defining a NEXTHOP, but maybe also in other mutations of the packet? Enter Policy-based Routing.
In a way, Policy-based Routing relates to General Routing like Extended Access Lists relate to Standard Access List.
How policy is build for routes
Policy routing has a distinct syntax notation in Cisco IOS CLI – the route-map. It works much like an access list, but consists of multiline sections. Each section of a policy (actually, route-map) has its sequence number (in order of processing). Usual notation for numbering is applied – count in tens: 10, 20, 30… The sections are processed in order, first match gets to process the packet.
This notation for line numbering goes way back in time. For example, I first encountered it while learning programming in high school, but it was there in the text books from the early eighties! It allows us to easily insert lines in-between those already present, when it is needed for purposes of quick modification or debugging. The best practice then is to “clean” the ordered list after the main work is done, i.e. to renumber lines back to 10-notation. I’ve seen tools on GitHub which do it for [Cisco IOS|ASA] access lists, not sure if there are any for route-maps.
Each section has a result – either a PERMIT or DENY statement. Its meaning depends on how the policy is used, for policy routing, a match on a PERMIT statement means to take action described in the relevant section; a DENY statement, if matched, will send the packet into the general routing process for destination-based routing. At the end or each route-map there is an implicit DENY statement matching all packets and thus sending them to be routed per destination.
In each section there is [0;$\inf$] MATCH statements. If there is no match statements in the section, it will work as a catch-all mechanism. If there are more than one match statement, they all must match (i.e. an AND logic operator is applied to combine them). For policy-based routing, each match statement may reference a number of things:
- An access list – either standard or extended access list (both IPv4 and IPv6)
- the length of a packet
- A MAC-address
- A VLAN number range
Actual options allowed for policy-based routing may differ depending on platform. Other applications of route-maps, such as route redistribution or route filtering make use of other MATCH rules.
After that, there is a set of SET statements, which contain the desired modifications to matched packets. Each of the statements is applied in order of appearance. For policy-based routing, the set statements may contain such modifications as:
- next hop – the adjacent router to which the packet should be passed
- next hop recursive – allows to reference a non-adjacent next hop
- interface – the output interface
- default next-hop – consult the routing table, and if there is no match, forward to this next-hop router
- default interface – consult the routing table, and if there is no match, use this interface for output
- precedence – allows to impose a specific IP precedence on the packet – used in QoS applications
- df – sets the DON FRAGMENT flag in the header (IPv4 only, as with IPv6 the packets must be fragmented at end hosts)
- vrf – pass the packet to a particular virtual router instance – basically, pass to a separate (non-default) routing table for processing
I will consider policy-based routing applications in my next post on routing