Friday, August 29, 2014

Advanced Cisco Routing: OSPF Metrics

Suppose there are multiple routes between hosts on a network? How does OSPF choose a preferred route? I'm a big fan of practical experience, so to answer this question, I fired up GNS3 and started building networks to find out:

There are two endpoints, R5 and R6 in this network. There is a core network consisting of R1, R2, R3 and R4 which provide the transport between these two endpoints. Looking at this network diagram, you can see that there are two routes that traffic between these endpoints might take: first, there is the route R1-R2-R3-R4; second, there is the much shorter route of R1-R4. You can make a logical argument for either of these routes being better. From R1, there are two paths to R4, one of which is across a FastEthernet interface, and the other of which is across a 10M Ethernet interface. From R1's perspective, route R1-R2-R3-R4, going through the FastEthernet interface, might appear to be better, since the FastEthernet interface has ten times the bandwidth of the Ethernet interface connecting R1 and R4. However, there are more hops on that route, and the Serial link between R2 and R3 is much slower than the Ethernet interface between R1 and R4. Consequently, a human with the complete picture of the network can see that R5-R1-R4-R6 is clearly the better path. Does OSPF see that, also?

R5#traceroute 192.168.2.2

Type escape sequence to abort.
Tracing the route to 192.168.2.2

1 192.168.1.1 4 msec 4 msec 4 msec
2 172.16.1.2 12 msec 8 msec 8 msec
3 192.168.2.2 28 msec 24 msec *
R5#

Yep. Like a human with a network diagram, OSPF forms a complete picture of the network topology and makes intelligent decisions about the best route between endpoints.

However, suppose the topology were different. What if R1-R4 were connected by a serial link and R1-R2-R3-R4 were all FastEthernet links, like so?:

In this case, there is only one hop on the R1-R4 path, whereas there are four hops on the R1-R2-R3-R4 path. However, the bandwidth across the FastEthernet links is much better than the bandwidth across the serial link. A human would most likely choose R1-R2-R3-R4 to pass the traffic. What does OSPF choose as the best path?
R5#traceroute 192.168.2.2

Type escape sequence to abort.
Tracing the route to 192.168.2.2

1 192.168.1.1 4 msec 8 msec 0 msec
2 172.16.2.2 16 msec 12 msec 12 msec
3 172.16.3.2 24 msec 24 msec 24 msec
4 172.16.4.2 36 msec 24 msec 28 msec
5 192.168.2.2 48 msec 40 msec *
R5#

Once again, OSPF uses its comprehensive view of the network to choose the best path between endpoints. However, if you need to force OSPF to choose a particular path, it is possible to do so by manually assigning a cost to a link, but that's a topic for another post ;)

Avanced Cisco Routing: Implementing OSPF in IPv6

So far, all of the labs have dealt exclusively with IPv4 -- what has traditionally just been called, "IP."  Today, let's look at configuring IPv6 on Cisco routers, since we are rapidly approaching the point where IPv4 will no longer suffice on the public Internet.

Consider the following network topology:

I am using the IPv6 address space 2001:dead:beef:0:0:0:0:0/64 (2001:dead:beef:0::/64) to create the subnets that I will use to address these routers.  I have decided that the subnet 2001:dead:beef::0/112 will be reserved for the loopback addresses on my core routers (far more than I need, but in real-life, that would provide room for expansion in the future).  The subnet 2001:dead:beef::1:0/112 will be reserved -- and subdivided -- for point-to-point networks, such as the serial links between the core routers.  Each LAN will be a /112 on 2001:dead:beef::x:0, where "x" is greater than 0 -- for example, 2001:dead:beef::1:0/112, 2001:dead:beef::2:0/112, etc.  I will use OPSFv6 to route between these various networks.

As I often do, I am using Cisco 3600-series routers for the core routers (ANCCR1, ENACR1, FAICR1 and HOMCR1) and Cisco 2600-series routers to simulate PCs attached to the routers' LANs.  Since the 2600 routers are the simplest to configure -- just a single Ethernet interface and a static route to the core routers -- that's where I started configuring this network:

faipc2(config)#int fa1/0
faipc2(config-if)#description Uplink to faicr1
faipc2(config-if)#ipv6 address 2001:dead:beef:0:0:0:3:2/112
faipc2(config-if)#ipv6 enable
faipc2(config-if)#no shut
faipc2(config-if)#exit
faipc2(config)#ipv6 route 0:0:0:0:0:0:0:0/0 2001:dead:beef:0:0:0:3:1
faipc2(config)#

That's all it takes to configure an IPv6 address on FA1/0 and to set up a static route to faicr1.  We'll repeat this set-up (with the appropriate IPv6 addresses and routes, of course) on R5-R9, but I won't duplicate the configurations here.

Once the "PC's" are configured, we'll start configuring the core routers.  Let's start with anccr1, since it's the most complex router on the network, having two Ethernet interfaces, two serial interfaces and a loopback interface:
anccr1(config)#int lo0
anccr1(config-if)#ipv6 address 2001:dead:beef::1/128
anccr1(config-if)#ipv6 enable
anccr1(config-if)#no shut
anccr1(config-if)#int fa1/0
anccr1(config-if)#desc Anchorage LAN 1
anccr1(config-if)#ipv6 address 2001:dead:beef::6:1/112
anccr1(config-if)#ipv6 enable
anccr1(config-if)#no shut
anccr1(config-if)#int fa2/0
anccr1(config-if)#desc Anchorage LAN 2
anccr1(config-if)#ipv6 address 2001:dead:beef::7:1/112
anccr1(config-if)#ipv6 enable
anccr1(config-if)#no shut
anccr1(config-if)#int s0/0
anccr1(config-if)#desc Uplink to faicr1
anccr1(config-if)#ipv6 address 2001:dead:beef::1:1/127
anccr1(config-if)#ipv6 enable
anccr1(config-if)#no shut
anccr1(config-if)#int s0/1
anccr1(config-if)#desc Uplink to enacr1
anccr1(config-if)#ipv6 address 2001:dead:beef::1:5/127
anccr1(config-if)#ipv6 enable
anccr1(config-if)#no shut

Just as in IPv4, by default, the router will know how to reach connected networks, but will not share routes with the other routers until a routing protocol (OSPF, BGP, EIGRP, etc.) is enabled.  However, at this point we should have two devices we can reach from anccr1: ancpc1 (R7 on the diagram) and ancpc2 (R8 on the diagram).  Let's try to ping them both:
anccr1#ping 2001:dead:beef::6:2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:dead:beef::6:2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/7/12 ms
anccr1#ping 2001:dead:beef::7:2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:dead:beef::7:2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/6/12 ms
anccr1#

Excellent!  We were able to ping both hosts.  Let's turn up enacr1 and see if we can ping across the serial link:
enacr1(config)#int fa1/0
enacr1(config-if)#desc Kenai LAN
enacr1(config-if)#ipv6 address 2001:dead:beef::4:1/112
enacr1(config-if)#ipv6 enable
enacr1(config-if)#no shut
enacr1(config-if)#int s0/1
enacr1(config-if)#desc Uplink to homcr1
enacr1(config-if)#ipv6 address 2001:dead:beef::1:9/127
enacr1(config-if)#ipv6 enable
enacr1(config-if)#no shut
enacr1(config-if)#int s0/0
enacr1(config-if)#desc Uplink to anccr1
enacr1(config-if)#ipv6 address 2001:dead:beef::1:6/127
enacr1(config-if)#ipv6 enable
enacr1(config-if)#no shut

Hmmm...something seems to be wrong.  I can ping the 2600 router ("LAN PC"), but not the Anchorage core router:
enacr1#ping 2001:dead:beef::1:5

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:dead:beef::1:5, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
enacr1#ping 2001:dead:beef::4:2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:dead:beef::4:2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 0/6/12 ms
enacr1#

We'll troubleshoot just like we would on an IPv4 network:
enacr1#sho ipv6 int brief
Serial0/0                  [up/up]
    FE80::CE02:14FF:FEA2:10
    2001:dead:beef::1:6
Serial0/1                  [up/up]
    FE80::CE02:14FF:FEA2:10
    2001:dead:beef::1:9
Serial0/2                  [administratively down/down]
    unassigned
Serial0/3                  [administratively down/down]
    unassigned
FastEthernet1/0            [up/up]
    FE80::CE02:14FF:FEA2:10
    2001:dead:beef::4:1
enacr1#
enacr1#sho ipv6 route
IPv6 Routing Table - 8 entries
Codes: C - Connected, L - Local, S - Static, R - RIP, B - BGP
       U - Per-user Static route
       I1 - ISIS L1, I2 - ISIS L2, IA - ISIS interarea, IS - ISIS summary
       O - OSPF intra, OI - OSPF inter, OE1 - OSPF ext 1, OE2 - OSPF ext 2
C   2001:dead:beef::1:6/127 [0/0]
     via ::, Serial0/0
L   2001:dead:beef::1:6/128 [0/0]
     via ::, Serial0/0
C   2001:dead:beef::1:8/127 [0/0]
     via ::, Serial0/1
L   2001:dead:beef::1:9/128 [0/0]
     via ::, Serial0/1
C   2001:dead:beef::4:0/112 [0/0]
     via ::, FastEthernet1/0
L   2001:dead:beef::4:1/128 [0/0]
     via ::, FastEthernet1/0
L   FE80::/10 [0/0]
     via ::, Null0
L   FF00::/8 [0/0]
     via ::, Null0
enacr1#

Hmmm...well, for one thing, we configured the IPv6 addresses on the serial ports as /127's on both routers rather than /126's.  In theory, this should work, but you might want to research /127's on an IPv6 network before using them.  For now, let's change the /127's to /126's, and see what happens:
anccr1#ping 2001:dead:beef::1:6

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:dead:beef::1:6, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/12/16 ms
anccr1#

That's better!  I'd love to say that the incorrect subnetting was an accidental typo, but in all honesty...I fubar'd the notation -- but it made for a great teaching moment, so I didn't edit it out of the blog entry, lol.

One last thing to try...by default, a router knows all of the subnets connected to it, and the "LAN PC's" have a default route to the local core router, so in theory, a "LAN PC" should be able to ping the loopback IPv6 address of its local LAN router.  Let's try it:
ancpc1#ping 2001:dead:beef::1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:dead:beef::1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/4/8 ms
ancpc1#

Sweet!  That worked just as expected.

Now, let's try enabling routing on the IPv6 network:
homcr1(config)#ipv6 router ospf 42
% IPv6 routing not enabled
homcr1(config)#
Eh?!?!  A quick search of the magic Google ball explains why: you must enable IPv6 unicast routing before you can turn up any IPv6 routing protocols.  <shrug>  Okay, whatever.  Let's do it:
homcr1(config)#ipv6 unicast-routing
homcr1(config)#ipv6 router ospf 42
04:44:40: %OSPFv3-4-NORTRID: OSPFv3 process 42 could not pick a router-id,
please configure manually

Ummm...okay.  I was just about to do that, anyway:
homcr1(config-rtr)#router-id 2001:dead:beef::4
                             ^
% Invalid input detected at '^' marker.

And we wonder why IPv6 is taking so long to adopt, sigh.  According to the spec, the OSPF router ID is technically NOT an IP address, but is instead a 32-bit number that is used to uniquely identify the router in it's OSPF area.  Since IP (v4) addresses happen to also be 32-bit numbers, that is what is typically used, but it is not a requirement.  The fact that Cisco, by default, will select one of the IPv4 addresses configured on the router to use as the router ID if you do not manually specify one muddies the issue, but that isn't really relevant here...except that we haven't configured any IPv4 addresses on the router, so OSPF can't arbitrarily snatch one to use as the router ID.  Back on track...let's assign a random 32-bit router ID to this router:
homcr1(config-rtr)#router-id 4.4.4.4

Next, there is no "network a.b.c.d e.f.g.h area i.j.k.l" command in IPv6 OSPF like there is in IPv4 OSPF.  Instead, we set the OSPF area globally, and tell the OSPF process what we would like to distribute:
homcr1(config-rtr)#area 0.0.0.0 range 2001:dead:beef::0/64
homcr1(config-rtr)#redistribute connected

However, that isn't sufficient to start sharing routes via IPv6 OSPF:
faicr1#sho ipv6 route
IPv6 Routing Table - 9 entries
Codes: C - Connected, L - Local, S - Static, R - RIP, B - BGP
       U - Per-user Static route
       I1 - ISIS L1, I2 - ISIS L2, IA - ISIS interarea, IS - ISIS summary
       O - OSPF intra, OI - OSPF inter, OE1 - OSPF ext 1, OE2 - OSPF ext 2
LC  2001:dead:beef::3/128 [0/0]
     via ::, Loopback0
C   2001:dead:beef::1:0/126 [0/0]
     via ::, Serial0/0
L   2001:dead:beef::1:2/128 [0/0]
     via ::, Serial0/0
C   2001:dead:beef::2:0/112 [0/0]
     via ::, FastEthernet1/0
L   2001:dead:beef::2:1/128 [0/0]
     via ::, FastEthernet1/0
C   2001:dead:beef::3:0/112 [0/0]
     via ::, FastEthernet2/0
L   2001:dead:beef::3:1/128 [0/0]
     via ::, FastEthernet2/0
L   FE80::/10 [0/0]
     via ::, Null0
L   FF00::/8 [0/0]
     via ::, Null0
faicr1#

In IPv6 OSPF, you have to enable the OSPF process in each interface that will be participating in OSPF:
faicr1#conf t
Enter configuration commands, one per line. End with CNTL/Z.
faicr1(config)#int s0/0
faicr1(config-if)#ipv6 ospf 42 area 0.0.0.0
faicr1(config-if)#exit
05:10:00: %OSPFv3-5-ADJCHG: Process 42, Nbr 1.1.1.1 on Serial0/0 from LOADING to FULL, Loading Done
faicr1(config)#exit
faicr1#sho ipv6 route
IPv6 Routing Table - 16 entries
Codes: C - Connected, L - Local, S - Static, R - RIP, B - BGP
       U - Per-user Static route
       I1 - ISIS L1, I2 - ISIS L2, IA - ISIS interarea, IS - ISIS summary
       O - OSPF intra, OI - OSPF inter, OE1 - OSPF ext 1, OE2 - OSPF ext 2
OE2  2001:dead:beef::1/128 [110/20]
     via FE80::CE01:14FF:FEA2:10, Serial0/0
OE2  2001:dead:beef::2/128 [110/20]
     via FE80::CE01:14FF:FEA2:10, Serial0/0
LC  2001:dead:beef::3/128 [0/0]
     via ::, Loopback0
C   2001:dead:beef::1:0/126 [0/0]
     via ::, Serial0/0
L   2001:dead:beef::1:2/128 [0/0]
     via ::, Serial0/0
O   2001:dead:beef::1:4/126 [110/128]
     via FE80::CE01:14FF:FEA2:10, Serial0/0
O   2001:dead:beef::1:8/126 [110/192]
     via FE80::CE01:14FF:FEA2:10, Serial0/0
C   2001:dead:beef::2:0/112 [0/0]
     via ::, FastEthernet1/0
L   2001:dead:beef::2:1/128 [0/0]
     via ::, FastEthernet1/0
C   2001:dead:beef::3:0/112 [0/0]
     via ::, FastEthernet2/0
L   2001:dead:beef::3:1/128 [0/0]
     via ::, FastEthernet2/0
OE2  2001:dead:beef::4:0/112 [110/20]
     via FE80::CE01:14FF:FEA2:10, Serial0/0
OE2  2001:dead:beef::6:0/112 [110/20]
     via FE80::CE01:14FF:FEA2:10, Serial0/0
OE2  2001:dead:beef::7:0/112 [110/20]
     via FE80::CE01:14FF:FEA2:10, Serial0/0
L   FE80::/10 [0/0]
     via ::, Null0
L   FF00::/8 [0/0]
     via ::, Null0
faicr1#

That's much better! Now we have routes from the other routers (which previously had OSPF enabled on their serial interfaces) showing up on the Fairbanks core router. Let's make sure our "LAN PC's&qout; can ping end-to-end:
hompc1#ping 2001:dead:beef::4:2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:dead:beef::4:2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/13/20 ms
hompc1#ping 2001:dead:beef::6:2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:dead:beef::6:2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/36/64 ms
hompc1#ping 2001:dead:beef::7:2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:dead:beef::7:2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/30/56 ms
hompc1#ping 2001:dead:beef::2:2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:dead:beef::2:2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/35/56 ms
hompc1#ping 2001:dead:beef::3:2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:dead:beef::3:2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/25/57 ms
hompc1#

Advanced Cisco Routing: Route Precedence

So far, all of our routing examples have been fairly straightforward. For example, in all of our examples so far, we have had clearly delineated subnets that do not conflict with each other. In general, I often use subnets within 10.0.0.0/8 and 192.168.0.0/16 for Ethernet or FastEthernet links, and I tend to use subnets within 172.16.0.0/12 for tunnels or serial links (point-to-point networks). This helps me keep various subnets straight in my mind while I am creating these labs, and makes it easy to see what type of network I am working with at a glance. However, in the real world, IP addressing schemes tend to be organic -- that is, the network admin(s) may have started out with an overall scheme in mind, but do to company mergers, changes in staffic, and the like, the addressing schemes tend to change over time, causing "islands" within larger subnets to be located on routes that differ significantly from the routes that contain the larger subnet. Consider this network, for example:


In this diagram, we see two companies, SmallCo and MegaCorp that have merged as the result of an aquisition. SmallCo has two offices, with routers R1 (a satellite location) and R2 (the main office router). As a result of the merger, SmallCo has migrated all of its LAN IP space into the subnet 10.2.0.0/16, and is using 172.16.100 for point-to-point networks. MegaCorp is using both the 10.0.0.0/8 and 192.168.0.0/16 subnets for its IP addressing. However, as far as routing is concerned, we now have a problem: SmallCo is using a subnet inside the 10.0.0.0/8 address range that MegaCorp is using internally. Fortunately, MegaCorp isn't using any addresses inside 10.2.0.0/16, but it means that the network admins can't just route 10.0.0.0/8 to its internal routers anymore, since 10.2.0.0/16 has to go to SmallCo's routers.

Or can they?

Suppose R1 and R2 are sharing routes via OSPF, and suppose there are static routes on both routers pointing 10.0.0.0/8 and 192.168.0.0/16 to R3. Will PCs (R4 and R5) on the two SmallCo LANs be able to reach each other? Will they be able to reach hosts on the 10-dot subnets within MegaCorp? Let's find out.

Here is the routing configuration on R1:
router ospf 42
router-id 10.2.7.129
log-adjacency-changes
redistribute connected subnets
network 172.16.100.20 0.0.0.3 area 0.0.0.0
!
ip classless
ip route 10.0.0.0 255.0.0.0 192.168.15.49
ip route 192.168.0.0 255.255.0.0 192.168.15.49

Here is the routing configuration on R2:
router ospf 42
router-id 10.2.6.1
log-adjacency-changes
redistribute connected subnets
network 172.16.100.20 0.0.0.3 area 0.0.0.0
!
ip classless
ip route 10.0.0.0 255.0.0.0 192.168.12.45
ip route 192.168.0.0 255.255.0.0 192.168.12.45

...and finally, here is the routing configuration for R3:
ip classless
ip route 10.254.0.0 255.255.0.0 192.168.12.46
ip route 10.254.7.128 255.255.255.192 192.168.15.50

If you ping from any of the various endpoints...:
R4#ping 10.2.6.236

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.2.6.236, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 28/62/152 ms
R4#ping 192.168.9.161

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.9.161, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/52/152 ms
R4#ping 10.10.100.221

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.10.100.221, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 16/38/68 ms
R4#


R7#ping 10.2.7.184

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.2.7.184, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 20/28/36 ms
R7#ping 10.2.6.236

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.2.6.236, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 20/24/32 ms
R7#ping 192.168.9.161

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 192.168.9.161, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 12/14/24 ms
R7#

This works because a route to a more specific subnet mask will ALWAYS override a more generic subnet mask in the routing tables. In this case, routes to 10.2.6.0/24 and 10.2.7.128/26 are more specific than the route to 10.0.0.0/8, so if the router sees a packet destined for one of these two subnets, it will route the packet to R2 or R1 (respectively) rather than to R3...even if the packet originates on R3.