This post represents the solution and explanation for quiz-2.
Have a look at the quiz and try solving it before reading this post.

I will start this article with one of the most important rule in OSPF regarding the best path selection: for the same prefix, OSPF uses the following order: O (intra-area) vs. O IA (inter-area) vs. O E1 (external type-1) vs. O E2 (external type-2)

But in the above scenario, in regards to net A (33.33.33.1/24 = Lo1 on R3), this rule is not very useful on R1 (or R2). Why?
Because the routes do not belong to the same OSPF process. Let's see: R1 has 2 paths for Net A:

  • net A (33.33.33.1/32) from R3 as intra-area (O) in OSPF process-id 1
  • net A (33.33.33.1/32) from R2 as external (O E2) in OSPF process-id 2

OSPF Redistribution

Since the process-id is different, R1 cannot apply the above mentioned rule, so in this case it treats them as coming from 2 different routing protocols. What happens when the router receives same prefix from 2 different routing protocols? It compares the Administrative Distance.

But in our case, the AD is same (110) for both internal OSPF Pid 1 and external OSPF Pid 2... so, it comes down to a race condition: whatever route is learned first it will be inserted into the routing table.

Now, the above process occurs also on R2, not only on R1... So, what happens if the OSPF database exchange with R3 takes longer on R1 (comparing to R2). All this results in suboptimal routing on R1 (or R2) seen here:

R1#trace 33.33.33.1

Type escape sequence to abort.
Tracing the route to 33.33.33.1

 1 172.16.1.2 20 msec 44 msec 16 msec
 2 192.168.1.3 40 msec 56 msec 20 msec

The problem becomes worse if the source of Net A (33.33.33.1/32), R3, looses OSPF peering with R1/R2 as this will cause a routing loop for Net A (shutdown fa0/0 on R3, as shown in the quiz):

R4#traceroute 33.33.33.1

Type escape sequence to abort.
Tracing the route to 33.33.33.1

 1 172.16.1.2 68 msec 20 msec 20 msec
 2 192.168.1.1 36 msec 48 msec 32 msec
 3 172.16.1.2 52 msec 32 msec 20 msec
 4 192.168.1.1 20 msec 56 msec 52 msec
 5 172.16.1.2 40 msec 60 msec 52 msec
 6 192.168.1.1 108 msec 44 msec 68 msec
 7 172.16.1.2 68 msec 96 msec 68 msec ...and so on...

How could we solve this? Well, remember where the problem started in the first place: comparing the AD of internal OSPF Pid-1 with the AD of external OSPF Pid-2. To solve this problem there are more options, but let's start by configuring both OSPF processes to have a higher AD for external routes:

router ospf 1
redistribute ospf 2 subnets
distance ospf external 222
!
router ospf 2
redistribute ospf 1 subnets
distance ospf external 222
OSPF Redistribution

This solves the initial problem, but introduces the same situation for any external prefixes learned via either OSPF Pid 1 or OSPF Pid 2 => those prefixes may be reached via suboptimal path or may loop indefinetely (see in the above picture the External Net X learned via OSPF Pid 1)

The solution to the new problem could be to configure different AD for the OSPF processes:

router ospf 1
redistribute ospf 2 subnets
distance ospf external 199
!
router ospf 2
redistribute ospf 1 subnets
distance ospf external 222
OSPF Redistribution - external AD

This will solve the problems for any external prefix (see Net X) learned via OSPF Pid-1, but will not solve the problem for any external prefix (see Net Y above) learned via OSPF Pid-2... so we can't find a general solution for all external prefixes learned via either OSPF Pid-1 or via OSPF Pid-2.

In the end, the solution will be to combine setting the administrative distance with a filtering method. You have you match the prefixes from one domain (with an ACL or a tag) and keep them from being re-advertised into the domain they originated from.
Let's see the solutions in detail:

Solution 1: different AD + filtering based on ACLs

Using the above configuration, you configure ACLs matching all prefixes originated or learned in each OSPF process:

router ospf 1
 redistribute ospf 2 subnets route-map OSPF_DOMAIN_2
 distance ospf external 222
!
router ospf 2
 redistribute ospf 1 subnets route-map OSPF_DOMAIN_1
 distance ospf external 222
!
route-map OSPF_DOMAIN_2 permit 10
 match ip address 2
!
route-map OSPF_DOMAIN_1 permit 10
 match ip address 1
!
access-list 1 permit 33.33.33.1
access-list 1 <net X> # all routes from OSPF Pid-1 (including external ones)
!
access-list 2 <net Y> # all routes from OSPF Pid-2 (including external ones)
  • Pro: it solves most of the problems
  • Con: you have to maintain long ACL with prefixes from each domain

Variant solution 1.1: instead of setting the AD for all external prefixes, you may opt to set the AD to prefixes identified by ACLs with command
distance 222 0.0.0.0 255.255.255.255 <acl>

Solution 2: filtering based on route tags

During the redistribution, you can set tags so all the prefixes that belong to same routing domain will share the same tag. Later, on the remote routers (second redistribution point), you will filter those prefixes based on tags.

Depending on whether the redistributed routing domains have the same AD (as in our case) or different (let's say: OSPF and EIGRP), you may need to perform filtering while installing/accepting the tagged prefixes in the routing table OR you may perform the filtering of the tagged prefixes while performing a new redistribution (back into the original domain).

Filtering the tagged routes while installing into the routing table works in all situations because if a route is not installed in the routing table, it will also not be redistributed back into the original domain=> hence you'll not create a routing loop.

router ospf 1
 redistribute ospf 2 subnets tag 2
 distribute-list route-map DENY_TAG_2 in
!
route-map DENY_TAG_2 deny 10
 match tag 2
route-map DENY_TAG_2 permit 20
!
!
router ospf 2
 redistribute ospf 1 subnets tag 1
 distribute-list route-map DENY_TAG_1 in
!
route-map DENY_TAG_1 deny 10
 match tag 1
route-map DENY_TAG_1 permit 20
OSPF Redistribution with tags
  • Pro: less administrative overhead (you don't have to maintain ACLs/prefix-list for every route that is learned)
  • Con: R1 and R2 does not accept each other's prefixes from the different routing domain (OSPF processes) due to the distribute-list

Variant solution 2.1

A variant solution is to perform the filtering during the redistribution (redistribute ospf <pid> subnets route-map DENY_TAG_X) instead of using distribute-list.

  • Pro: R1 / R2 will accept each other's prefixes (see above Cons)
  • Con: suboptimal routing for R1/R2 due to the fact that they accepts each other's routing

Solution 3: Filter redistributed prefixes with a AD of 255

In previous solution, redistribution routers were filtering the redistributed prefixes based on tags. This time, we can do the same filtering by setting the administrative distance to 255 - so, we'll setup the following rule: on all redistribution points/routers (in our case, R1 & R2), do not accept any prefix that is learned from the other/redundant redistribution routers:

R1
router ospf 1
 redistribute ospf 2 subnet
 distance 255 2.2.2.123 0.0.0.0 ACL_DOMAIN_2
!
ip access-list stand ACL_DOMAIN_2 ... # prefixes learned via Pid-2
!
router ospf 2
 redistribute ospf 1 subnet
 distance 255 2.2.2.124 0.0.0.0 ACL_DOMAIN_1
!
ip access-list stand ACL_DOMAIN_1 ... # prefixes learned via Pid-1
R2
router ospf 1
 redistribute ospf 2 subnet
 distance 255 1.1.1.123 0.0.0.0 ACL_DOMAIN_2
!
ip access-list stand ACL_DOMAIN_2 ... # prefixes learned via Pid-2
!
router ospf 2
 redistribute ospf 1 subnet
 distance 255 1.1.1.124 0.0.0.0 ACL_DOMAIN_1
!
ip access-list stand ACL_DOMAIN_1 ... # prefixes learned via Pid-1

Again, same as the previous solution, this one also has the drawbacks of maintaining ACLs for each routing domain plus the fact that R1/R2 don't backup each other (because they don't accept each other's prefixes).

As always, posts about OSPF are veeery long, but hopefully useful.
Thanks for your comments on the initial quiz.