When Route Redistribution goes bad - Routing Loops and Route feedback (2.90)


When we are redistributing from one protocol into another, we find that with one point of redistribution everything is fine, but when we have multiple points of redistribution we can start to encounter problems, namely routing loops and route feedback. Thankfully these can be fixed with a few commands.

Routing loops

OSPF and RIP IOU NetMap


In the diagram above we are redistributing RIP into OSPF, and from OSPF into RIP. Ignore the mis-labelled interface for Router C (the interface in the RIP network is actually e0/1), I made a mistake in my original netmap. I wondered why things didn't work properly. Originally I did this in Packet Tracer, only to find a serious limitation was the lack of distribute-lists and limitations on the distance command.

If you want to follow this post through, then you can download the IOU lab from here.

First we begin with very straight-forward ospf and rip networks. Picking RouterA and RouterF, we quickly check that the basics are all plumbed in:

OSPF on Cisco IOU

OSPF looks good, so lets just check rip

RIP on Cisco IOU

OK, all looks good.

The routing tables on routers C and D look like this

Cisco IOU routing ospf and rip

Lets have a quick look at the routing tables of routers A and F

Cisco IOU routing ospf and rip

Making a routing loop

To create the routing loop we need to mutually redistribute OSPF and RIP on routers C and D. The commands are identical for both.

Cisco IOU mutual redistribution of rip and ospf

And we can see (using the "sh ip route" command) the contents of the routing table:


Now we can start to see the problem.

Router C which has an interface in the RIP network, has a route to the 10.1.X.0 through router A (apart from its own directly connected 10.1.1.0/24 network) - which is kind of in the wrong direction. Similarly Router D has routes all of the 10.1.X networks (apart from its own directly connected 10.1.5.0/24 network) through Router B. Again really this is in the wrong direction.

The reason for this because the AD (Administrative Distance) of OSPF (110) is lower than the AD for RIP (120), and therefore is the prefered route. The AD can be seen as the first number in the square brackets [110/1] and [120/1]. Therefore to reach the non-connected networks, Routers C and D will prefer the sub-optimal path through OSPF.

The end effect is that if Router C sends a a packet destined for the 10.1.5.0/24 network it will go to Router A first (192.168.1.1). This is Router A's routing table:

sh ip route loop

Router A will pass the packet to Router B, and from B it passes to Router D. This does not present its-self as much of an issue, but look at the routes for the 10.1.4/0/24 network.

A packet to the 10.1.4.0/24 network originating from Router C would pass to Router A. From Router A it would pass to Router B, and from B to D. Now here we see the loop:

cisco ios redistribution routing loop

The routing table for Router B is on the left and for Router D is on the right. As you can see Router B prefers Router D as the best route to the 10.1.4.0 network, and Router D prefers Router B as the best route. Thus we have a loop.

Fixing a routing loop

Thankfully all is not lost (well, maybe a few packets along the way), and we have two ways of fixing this scenario.

Fixing a routing loop with a distribution-list

The first method is to use a distribution-list and attach it to the interface we want to prevent accepting routes from the wrong side. The configuration on Router C would be as follows:

RouterC(config)# access-list 10 deny 10.1.2.0 0.0.0.255
RouterC(config)# access-list 10 deny 10.1.3.0 0.0.0.255
RouterC(config)# access-list 10 deny 10.1.4.0 0.0.0.255
RouterC(config)# access-list 10 deny 10.1.5.0 0.0.0.255
RouterC(config)# access-list 10 permit any

RouterC(config)# router opsf 1
RouterC(config-router)# distribute-list 10 in ethernet0/0

And Router D would look similar:

RouterC(config)# access-list 10 deny 10.1.1.0 0.0.0.255
RouterC(config)# access-list 10 deny 10.1.2.0 0.0.0.255
RouterC(config)# access-list 10 deny 10.1.3.0 0.0.0.255
RouterC(config)# access-list 10 deny 10.1.4.0 0.0.0.255
RouterC(config)# access-list 10 permit any

RouterC(config)# router opsf 1
RouterC(config-router)# distribute-list 10 in ethernet0/0

These access-lists deny the RIP networks specified, whilst permitting all the other networks. We can see this taking effect immediately in the routing table:

fixing routing loop with distribution-list

The downside of this method is that any form of redundancy is also lost. If Router C lost its e0/1 interface it would not be able to select an alternative path (i.e. through the RIP network) for the other OSPF networks.

distribution-list ios ospf rip


Fixing a routing loop with the distance command

The second method we have available is to tweak the AD for the specific routes. it is very similar to the first method, but with a few changes, we can either lower the AD of the routes learned through RIP, or raise the AD of the external OSPF learned routes. Again we start with an access list:

RouterC(config)# access-list 10 permit 10.1.2.0 0.0.0.255
RouterC(config)# access-list 10 permit 10.1.3.0 0.0.0.255
RouterC(config)# access-list 10 permit 10.1.4.0 0.0.0.255
RouterC(config)# access-list 10 permit 10.1.5.0 0.0.0.255
RouterC(config)# access-list 10 deny any

RouterC(config)# router rip
RouterC(config-router)# distance 70 10.1.1.0 0.0.0.255 10

Here we are applying a an AD of 70 for the routes specified in access list 10. Again Router D's config would be similar, but I think you can see what needs changing, so I wont put the config here.

The end result is that the routes originating from RIP will now have a lower AD than the routes that have been redistributed from OSPF. This eliminates the routing loop.

tune distance metrics rip ospf redistribution


If we decided that we wanted to use the second method and raise the AD for the external OSPF learned routes then we can do this with one line, and do not need the access list:

RouterC(config)# router ospf 1
RouterC(config-router)# distance ospf external 240

Router C and Router D then replaced the externally learned routes with the routers learned by its own RIP process:

change ospf external ad administrative distance

change ospf external ad administrative distance

Router D is probably the best example of the process, as the screenshot managed to catch the transition in routes, firstly as their AD is increased to 240, and then, moments later, as these routes are replaced by the ones originating from within RIP.

So that's routing loops taken care of, now lets move on.

Route feedback

The OSPF routes that have been redistributed into RIP by Router C will also reach Router D, and will again be redistributed back into OSPF. hence the term "feedback".

The feedback could very well cause Router B to prefer the route through RouterD for the 192.168.2.0/24 network. This is called suboptimal routing.

clearly we want to make sure that no re-injection occurs. We can do this through distribution lists and by using the distance command, but lets look at route tags instead.

We can tag routes in order to identify and filter them. The tag is retained as it passes from router to router. So a tag that is applied when it is redistributed into RIP (say from Router C) retains its tag and can be used by another router (Router D) to be filtered out.

We use route-maps in order to apply tags, these are similar to access-lists by using permit or deny statements but also allow attributes to be matched and set.

Using RouterC are the example, the route maps would look like this (I have added line numbers for reference later on) :

1. RouterC(config)# route-map ospf->rip deny 5
2. RouterC(config-route-map)# match tag 33
3. RouterC(config)# route-map ospf->rip permit 15
4. RouterC(config-route-map)# set tag 44
5. RouterC(config-route-map)# exit

6. RouterC(config)# router rip
7. RouterC(config-router)# redistribute ospf 1 route-map ospf->rip

8. RouterC(config)# route-map rip->ospf deny 5
9. RouterC(config-route-map)# match tag 44
10. RouterC(config-route-map)# route-map rip->ospf permit 15
11. RouterC(config-route-map)# set tag 33

12. RouterC(config)# router ospf 1
13. RouterC(config-router)# redistribute rip route-map rip->ospf

So here any OSPF routes that are being redistributed into RIP have a tag of 44 set (line 4). When RIP is redistributed back into OSPF any tag that matches 44 is denied (lines 8 and 9).

When RIP routes are being redistributed into OSPF they have a tag of 33 set (line 11). These routes are denied (line 1) when being redistributed from OSPF back into RIP (line 2). The ordering of these statements is crucial.

setting tag using route-map ospf rip redistribution

We can see above the tag being added to the routes. Unfortunately I could not get and routes to feedback to show you this in action, sometimes its annoying when things work properly!

Nonetheless, the end result is that routes will not be redistributed back into the routing domain from where they originated.

I hope you have found this useful.

CCIE #49337, author of CCNA and Beyond, BGP for Cisco Networks, MPLS for Cisco Networks, VPNs and NAT for Cisco Networks.

Related Posts

Previous
Next Post »