Wednesday, September 24, 2014

Advanced Cisco Routing -- MPLS VRFs

Several years ago, I worked for a telecommunications provider that was rolling out what I believe was one of the very first -- if the THE very first -- MPLS network in the state of Alaska. The network admins often joked that their network was not just cutting edge; it was bleeding edge. At that time, the network admins worked very closely with Cisco to build and troubleshoot the network, since Cisco was still making sure the tech worked as advertised. Since then, technology has changed, and MPLS has become much more common, even though one of the major drivers that led to the development of MPLS has become more or less a moot point: hardware has improved to the point, where it is no longer significantly faster to switch or route traffic based upon labels than IP or MAC addresses.

For example, the company I currently work for has implemented a ring (!) network with an MPLS core, simply because using MPLS makes it easier for us to configure customer networks across our service provider network. Rather than visiting each node in the ring to create a VLAN for that customer, then adding the VLAN to a topology group (again, on every node in the network), we simply create a VLL or VPLS on the endpoints, and we're done. It's a configuration change on two nodes in the case of a VLL, rather than every node in the ring (with VPLS, it depends upon how many endpoints the client requires, so in some cases, there isn't much to be gained by using MPLS rather than a plain VLAN, and a VPLS introduces some overhead into the network that a VLAN doesn't).

In this lab, we'll create a "service-provider" network in GNS3 consisting of three routers, R1, R2 and R3, and two customer networks, R4 and R5 belonging to one customer, and R6 and R7 belonging to a second customer. The network topology looks like this:


Disclaimer: This lab was created using Cisco 2600-series routers with IOS version 12.3. This is a really, really old version of code, on really, really old (virtual) hardware, since that's all I have access to, currently. Consequently, Cisco's implementation of MPLS may be somewhat different on modern hardware and firmware versions. Hopefully, this will be close enough to get you started, however.

Since both customer networks are Layer-3 (routed) networks, we will use VRF's to logically separate the two customer networks from each other. In this sense, a VRF can more or less be considered to be the Layer-3 equivalent of a VLAN: the VRF's will partition the service provider network into to separate logical networks, including routing tables, that keep addressing and routing from the customer networks from interfering with each other. This has two major implications: first, the two customers in our lab don't have to coordinate IP addressing with each other (in fact, in our example, R4 and R7 have the exact same IP address and subnet!); second, the service provider will participate in the customer's routing!

Let's get started. First, we'll set up the service provider network, including the routing process for the network core. On R1:
interface Loopback0
ip address 10.10.10.1 255.255.255.255
!
interface Serial0/0
ip address 192.168.12.1 255.255.255.0
!
interface Serial0/1
ip address 192.168.13.1 255.255.255.0
!
router ospf 1138
router-id 10.10.10.1
log-adjacency-changes
network 10.10.10.1 0.0.0.0 area 0.0.0.0
network 192.168.12.0 0.0.0.255 area 0.0.0.0
network 192.168.13.0 0.0.0.255 area 0.0.0.0
!

R2 and R3 have similar configurations, and none of this is new, so I won't repeat their configs here.

Next, on a Cisco router, we have to enable CEF (Cisco Express Forwarding). It's trivial to do:
R1(config)#ip cef

Next, we create the two VRFs. Technically, you don't need MPLS to create a VRF (Cisco calls this "VRF Lite"), nor do you need VRFs to run MPLS (for instance, if you are using VLLs or VPLS'). However, VRFs and MPLS work very well together, and for this lab, they solve the problem we have quite handily:
ip vrf left
rd 100:1
route-target export 100:1
route-target import 100:1
!
ip vrf right
rd 200:1
route-target export 200:1
route-target import 200:1
!

As you can see in the configuration above, I was highly original with the name of the VRFs, using "left" for routers R4 and R5, and "right" for R6 and R7. When implementing your own MPLS networks, I'd recommend keeping the VRF names short, easy to type, and easy to remember, as you'll be using them quite a bit in the router configurations. After creating the two VRFs, we use the "rd <AS:nn" command to create the "route distinguisher," using AS 100 for VRF left and AS 200 for VRF right. This is the label that you will be using in various places to differentiate between the two customer routing tables that you will be using in this network. According to Cisco's context-sensitive help function, you can also use an IP address rather than an AS number for the route distinguisher, but why type more than you have to? AS numbers are shorter! ;)

After creating your two VRFs, you next enable MPLS on the network interfaces that will be part of your MPLS core. In this case, that is S0/0 and S0/1 on R1, R2 and R3: interface Serial0/0
mpls ip

Just for giggles, exit out of configuration mode (or stay in config mode and prepend the following command with the word "do") and run "sho run":
interface Serial0/0
ip address 192.168.12.1 255.255.255.0
tag-switching ip
!
interface Serial0/1
ip address 192.168.13.1 255.255.255.0
tag-switching ip
!

Wait a minute...we didn't type "tag-switching ip" in the Serial interface configuration! We used "mpls ip!" What gives? Well, way back when MPLS was still being developed, Cisco was doing essentially the same thing, but called it "tag switching." When the standard was formalized, the technology was given the name MPLS, and Cisco implemented both the tag-switching and mpls commands on the command line. As I understand, there are some slight differences between the tag-switching and mpls command -- and I'm not sure what, exactly those difference might be, so I won't elaborate on that rather vague statement, except to say that you should probably stick with the mpls command, if that's what you are actually trying to build -- but the "show run" output rewrites either command as "tag-switching."

At this point, you know have a working MPLS core, as can be proven by running the "show mpls ldp neighbor" command:
R1#sho mpls ldp neighbor
    Peer TDP Ident: 10.10.10.3:0; Local TDP Ident 10.10.10.1:0
        TCP connection: 10.10.10.3.11008 - 10.10.10.1.711
        State: Oper; PIEs sent/rcvd: 165/165; Downstream
        Up time: 02:19:39
        TDP discovery sources:
          Serial0/1, Src IP addr: 192.168.13.3
        Addresses bound to peer TDP Ident:
          192.168.13.3    10.10.10.3      192.168.23.3    
    Peer TDP Ident: 10.10.10.2:0; Local TDP Ident 10.10.10.1:0
        TCP connection: 10.10.10.2.11004 - 10.10.10.1.711
        State: Oper; PIEs sent/rcvd: 167/166; Downstream
        Up time: 02:19:38
        TDP discovery sources:
          Serial0/0, Src IP addr: 192.168.12.2
        Addresses bound to peer TDP Ident:
          192.168.12.2    10.10.10.2      192.168.23.2    
R1#

Now, we need to tell MPLS which interfaces will be accepting traffic that should be encapsulated inside the MPLS label. This is done with the "ip vrf forwarding..." command. Let's also configure the IP addresses on the customer-facing Ethernet interfaces as we do this:
R1(config)#int eth0/0
R1(config-if)#ip vrf forwaring left
R1(config-if)#ip address 172.16.0.1 255.255.255.252
R1(config-if)#no shut

The only difference between a typical interface configuration and what we did here is that we used the "ip vrf forwarding left" command to tell the MPLS process that this interface is an endpoint of the VRF "left" tunnel(s). Do the same thing for Eth0/1 on R1, and for both E0/0 and E0/1 on R2 and R3, as well.

Be careful here! If you apply the IP address before you run the "ip vrf forwarding..." command, IOS will display an error message telling you that the IP address has been removed from the interface configuration! If you don't see the warning, you can spend quite a while trying to figure out why you aren't seeing the routes you expect across your MPLS core (DAMHIKT!)

This is where things start to get fun. You've basically got a complete MPLS configuration now -- you've enabled MPLS on the various network interfaces, you've got MPLS distributing labels for the various routes, and you can see the MPLS peering is working as it should. However, there is one last piece of the puzzle left: now, you need a way to distribute routes across your MPLS core. First, apply the IP addresses and routing processes to your "customer" routers just as you normally would if R4/R5 and R6/R7 were directly connected to each other. For example, on R4:
interface Loopback0
ip address 10.10.10.4 255.255.255.255
!
interface Ethernet0/0
ip address 172.16.0.2 255.255.255.252
half-duplex
!
router ospf 42
router-id 10.10.10.4
log-adjacency-changes
redistribute connected subnets
network 172.16.0.0 0.0.0.3 area 0.0.0.0
!

If you're paying attention, this is the point where you might scratch your head and object, "Wait a minute...with the 'network 172.16.0.0 0.0.0.3 area 0.0.0.0' command, I'm advertising my OSPF routing process to the service provider!" And you'd be exactly right. With MPLS, the service provider participates in your routing process, but because your traffic is being encapsulated in MPLS, that routing process is only participating with your other endpoints. In this example, R4 and R5 will share routes through the service provider's network, but will not see routes from R6 and R7 (and vice versa).

To accomplish this task on the service provider's network, the service provider will need to turn up separate OSPF process for each customer. In the lab, I also created separate loopback interfaces for each OSPF process because OSPF will complain if you try to enable OSPF without including any local interfaces in the process -- for example, on R2, if I try to turn up an OSPF process for VRF "right" (Edit: I'm not sure it's necessary to turn up OSPF for VRF "right" on R2 or VRF "left" on R3, as we will be setting up BGP to share routes between the OSPF processes; I'll investigate this in a later post). However, when turning up a separate OSPF process, you must tell OSPF which VRF this routing process belongs to:
interface Loopback1
description loopback for OSPF 100 -- VRF LEFT
ip vrf forwarding left
ip address 10.0.100.1 255.255.255.255
!
interface Loopback2
description loopback for OSPF 200 -- VRF RIGHT
ip vrf forwarding right
ip address 10.0.200.1 255.255.255.255
!
router ospf 100 vrf left
router-id 10.0.100.1
network 172.16.0.0 0.0.0.3 area 0.0.0.0
!
router ospf 200 vrf right
router-id 10.0.200.1
network 172.16.0.0 0.0.0.3 area 0.0.0.0
!

Notice that I included the "ip vrf forwaring..." command on the loopback interfaces!

If you execute the "sho route" command on any of the customer routers now, however, you will see that they are only aware of the locally connected routes and the loopback interface of the locally connected service provider router (i.e., R4 will only see the IP address of loopback1 on R1, R7 will only see the IP address of loopback2 on R1, etc.). This is because the OSPF processes that we just turned up are only sharing routes with the customer router connected to their Ethernet interface (OSPF 100 on R1 is only sharing routes through eth0/0 to R4, etc.). To enable routing across the MPLS core, we need to enable another routing process (!) to redistribute routes between these routing processes. If that sounds like a perfect job for BGP, you are exactly right:
router bgp 65510
no synchronization
bgp log-neighbor-changes
neighbor 10.10.10.2 remote-as 65510
neighbor 10.10.10.2 update-source Loopback0
neighbor 10.10.10.3 remote-as 65510
neighbor 10.10.10.3 update-source Loopback0
no auto-summary
!
address-family vpnv4
neighbor 10.10.10.2 activate
neighbor 10.10.10.2 send-community extended
neighbor 10.10.10.3 activate
neighbor 10.10.10.3 send-community extended
exit-address-family
!
address-family ipv4 vrf right
redistribute ospf 200
no auto-summary
no synchronization
exit-address-family
! address-family ipv4 vrf left
redistribute ospf 100
no auto-summary
no synchronization
exit-address-family
!

Notice the "address-family ipv4 vrf left" and "address-family ipv4 vrf right" statements. Under these statements, we have "redistribute ospf <process ID>" commands. These commands tell BGP to share routes learned via these OSPF process to the appropriate VRFs. That is, BGP should share routes learned via OSPF process 100 with VRF "left" and OSPF process 200 with VRF "right." This is good, but not sufficient. BGP will now know about any routes that OSPF knows, but OSPF doesn't yet know about all of the routes that BGP has in its routing table (you can verify this by running the "show ip route vrf left" and "show ip route vrf right" commands on any of the service provider routers). Let's take care of that now:
R1(config)#router ospf 100
R1(config-router)#redistribute bgp 65510 subnets
R1(config-router)#router ospf 200
R1(config-router)#redistribute bgp 65510 subnets

With this final configuration command, you should now have routes across the MPLS core between the customer routers. R4 should be able to ping/telnet/etc. to R5 (and vice versa) and R6 should be able to ping/telnet/etc. to R7 (and vice versa). However, neither R4 nor R5 should be able to communicate with R6 or R7.

Troubleshooting:
Enabling MPLS introduces a couple of complications to troubleshooting. As I mentioned earlier, I was fortunate enough to be an admin at a telco that was building out an MPLS core back in my early days of system and network administration. On one occasion, I saw an alarm for a customer's network, and logged into one of the MPLS edge routers to try to troubleshoot. However, when I tried to ping the customer's router, I was dismayed to find that my router apparently didn't have a route to that host. You can see this for yourself by attempting to ping a customer router from R1, R2 or R3:
R1#ping 172.16.2.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 172.16.2.2, timeout is 2 seconds:
.....
Success rate is 0 percent (0/5)
R1#
If you try "show route," you'll see a similar issue:
R1#sho ip route
<...snip...>
C    192.168.12.0/24 is directly connected, Serial0/0
C    192.168.13.0/24 is directly connected, Serial0/1
     10.0.0.0/32 is subnetted, 3 subnets
O       10.10.10.2 [110/65] via 192.168.12.2, 01:09:36, Serial0/0
O       10.10.10.3 [110/65] via 192.168.13.3, 01:09:36, Serial0/1
C       10.10.10.1 is directly connected, Loopback0
O    192.168.23.0/24 [110/128] via 192.168.13.3, 01:09:36, Serial0/1
                     [110/128] via 192.168.12.2, 01:09:36, Serial0/0
R1#

If you'll notice, all of the customer routers were configured with 172.16.x.y IP addresses, but there are no 172.16.x.y IP addresses in the routing table on R1. Yet, if you try a ping from R4 to R5 (or R6 to R7), you will see that it works:
R4#ping 172.16.2.2

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

How is this possible?

If you'll recall, I commented earlier that MPLS is rather like the Layer-3 equivalent of a VLAN, in that MPLS encapsulates the routing tables of the various VRFs into their own logical partitions, and that these routing tables are not shared amongst other VRFs. Nor are they shared with the global routing table of the service provider routers. If you want to view the routing tables inside a VRF or ping across the VRF, you have to explicitly tell the router so:
R1#ping vrf left 172.16.2.2

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 172.16.2.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/36/140 ms
R1#sho ip route vrf left

Routing Table: left
<...snip...&rt;
Gateway of last resort is not set

     172.16.0.0/30 is subnetted, 2 subnets
C       172.16.0.0 is directly connected, Ethernet0/0
B       172.16.2.0 [200/0] via 10.10.10.2, 03:01:06
     10.0.0.0/32 is subnetted, 2 subnets
O E2    10.10.10.4 [110/20] via 172.16.0.2, 01:17:46, Ethernet0/0
C       10.0.100.1 is directly connected, Loopback1
R1#

As a fellow network admin and blogger so eloquently put it, "Pretty much any command that you would normally use, add 'vrf <vrf name>' to it." This tells the router that you are specifically asking about the routing tables inside the specified VRF, which makes sense, if you think about it. In this lab, both R4 and R7 have the same IP address. From the service provider router's standpoint, how would it know whether it should ping R4 or R7 if all you did was "ping 172.16.0.2?" Consequently, you have to explicitly tell the router that it is to ping 172.16.0.2 inside VRF "left" (for example).

For more on the subject, check out the following web pages that I found to be helpful while trying to learn how to configure MPLS on Cisco routers:
Packet Life: Creating MPLS VPNs
Cisco Dreamer: MPLS Basics
Router Jockey: Cisco MPLS VRF Configuration and Demo

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.

Wednesday, July 30, 2014

Advanced Cisco Routing: GRE Tunnels

Suppose you had a network that spanned an untrusted carrier's network -- say, the Internet, for example. A wise admin probably would not be comfortable broadcasting company data across this untrusted network; any number of common LAN protocols, such as POP3, CIFS, HTTP, Telnet, etc. could potentially leak confidential data, like user names and passwords, to anyone who happened to be listening in. Even on relatively trustworthy networks such as leased lines or Metro-Ethernet E-Line or E-Tree services, a simple configuration error could result in propagating company data to other organizations on that network.

One solution to this problem is "tunneling" -- that is, encapsulating the raw TCP/IP traffic into another format. This is often used to create VPN's, or "Virtual Private Networks." A tunnel does not necessarily have to be encrypted, although it frequently is.

One protocol that is used on Cisco devices to create tunnels is GRE, which will be the focus of today's post.

Consider the following network:

In this example, I have created two LAN segments, one in Anchorage (R3 and R5) and one in Bethel(R4 and R6), connected by a service provider's network (R1 and R2). The configuration on R1 and R2 are very straightforward: turn up the necessary network interfaces, set up OSPF to share routes between R1 and R2, then configure BGP to peer with the Anchorage and Bethel routers (R3 and R4), all of which we've done before. R5 and R6 are also very straightforward: turn up FA1/0 on both routers, assign the appropriate IP addresses to each router, then set up a default route through R3 for R5 and through R4 for R6. As usual, these two routers are simply simulating PCs on the internal LAN.

R3 and R4 are the routers that where the magic happens in this lab. Essentially, a tunnel interface is just a logical interface on the router that is configured much like a physical interface. For GRE, the interface name is "Tunnel1" and the IP address of the tunnel interface is configured exactly like the IP address of any other interface on the router. On R3...:
interface Tunnel1
ip address 10.255.255.1 255.255.255.252


R4, of course, is configured with a tunnel IP address of 10.255.255.2/30.

Next, you must configure a tunnel source and a tunnel destination. That is, you must tell the router what interface you want the tunnel to terminate at on the local router ("tunnel source") and what router the far end of the interface should exist upon ("tunnel destination"). On R3, also under the "interface Tunnel1" configuration...:
tunnel source 172.16.0.2
tunnel destination 172.16.1.2


There is one additional caveat to consider, and this is one that is easy to forget. On TCP/IP networks, there is a parameter known as MTU size. Essentially, this is the largest size of a packet that a network device can forward without having to break the packet into smaller pieces. Consider it like this: if you have a shipment that is delivered to you in a semi truck, but you need to carry that shipment in your pickup truck, you will have to make several trips to deliver the load, right? Same thing in networking. If one network device can handle a 1500 byte packet, but the next device can only handle a 1400 byte packet, then the second network device will have to break the packet into a 1400 byte chunk, then send the remaining 100 bytes in a second chunk. This is called "fragmentation." MTU size becomes an issue with GRE tunnels, because GRE adds several bytes to the packet size when it encapsulates a TCP packet. Consequently, if your network can only support 1500 byte MTUs, and you are receiving 1500 byte packets from, say, a LAN interface, then you will have a GRE-encapsulated packet that is larger than 1500 bytes exiting through your WAN interface. You can avoid this by setting the MTU size and adjusting the maximum packet size that the tunnel will encapsulate. This is done with two commands in the tunnel interface setting:
ip mtu 1460
ip tcp adjust-mss 1420


The complete tunnel interface configuration looks like this:
interface Tunnel1
ip address 10.255.255.1 255.255.255.252
ip mtu 1460
ip tcp adjust-mss 1420
tunnel source 172.16.0.2
tunnel destination 172.16.1.2

There is one last factor to consider. Since tunnels are used to isolate certain types of traffic, for example, LAN traffic, you probably don't want to advertise all of your routes when tunneling between two networks. In this lab, I modeled a very common scenario: two LAN networks with a tunnel to allow them to communicate over a public, untrusted network. This is, in fact, exactly how a network I manage in my day job is built: two LAN networks with a VPN tunnel across the Internet to bridge them together. Obviously, I don't want to advertise routes to my internal, RFC-1918 networks to the Internet, nor do I want the entire Internet routing tables stored on my LAN routers. To address this, I set up BGP peering between R3 and R1, and between R4 and R2, to provide routes to public (Internet) hosts (note: yes, I'm using private IP space on all of these hosts. Just pretend that 192.168.0.0/16 is private IP space, but 10.0.0.0/8 and 172.16.0.0/12 are public for this lab). Then, I set up OSPF to advertise routes to my LAN networks only across the GRE tunnel. R3 and R4 are NOT sharing their OSPF routes with R1 or R2.

To do this, I first created the access list and route map to match the LAN network on each router. The config is identical on R3 and R4:
access-list 10 permit 192.168.0.0 0.0.255.255
!
route-map lan permit 10
match ip address 10

Then, I applied the route maps to the OSPF configuration on each router. On R3:
router ospf 2112
router-id 10.255.255.1
log-adjacency-changes
redistribute connected subnets route-map lan
network 10.255.255.0 0.0.0.3 area 0

...and on R4:
router ospf 2112
router-id 10.255.255.2
log-adjacency-changes
redistribute connected subnets route-map lan
network 10.255.255.0 0.0.0.3 area 0

For BGP, R3 and R4 are essentially set up to receive routes only. On R3:
router bgp 64513
bgp log-neighbor-changes
neighbor 172.16.0.1 remote-as 64512
!
address-family ipv4
neighbor 172.16.0.1 activate
no auto-summary
no synchronization
exit-address-family

...and on R4:
router bgp 64515
bgp log-neighbor-changes
neighbor 172.16.1.1 remote-as 64514
!
address-family ipv4
neighbor 172.16.1.1 activate
no auto-summary
no synchronization
exit-address-family

With that, I have a virtual connection from R3 to R4, as shown by the traceroute from R5 to R6:
R5#traceroute 192.168.1.2

Type escape sequence to abort.
Tracing the route to 192.168.1.2

1 192.168.0.1 0 msec 0 msec 8 msec
2 10.255.255.2 28 msec 24 msec 40 msec
3 192.168.1.2 32 msec 24 msec *
R5#

Notice that the traceroute does not show that it crossed 172.16.0.0/30, 10.0.0.0/30 or 172.16.1.0/30? It appears to go directly from R3 to R4. That is due to the tunnel that bridges R3 and R4 together. Even though, in reality, the traffic is indeed passing through the "ISP" network, to the LAN hosts, it is as if R3 has a direct physical connection to R4.

Monday, July 14, 2014

Advanced Cisco Routing -- Route Maps

So far, all of our routing examples have been pretty straight-forward: to reach network "A" you take route "A," and to reach network "B" you take route "B," etc. Suppose, however, that you need to filter routes between different WAN sites? Specifically, consider the following list of requirements:

  1. Multiple WAN sites with RFC-1918 IP space on the inside of the networks;
  2. Direct Nat'ed Internet links at each WAN site;
  3. Point-to-Point links (T1's, VPN tunnels, etc.) between WAN sites to route the internal LANs together;
  4. OSPF routing between internal LAN subnets.


In this case, you can use a route map to filter what networks OSPF is advertising. Here's how you do it:

First, here is the network topology for our example:
In this drawing, we'll use router R1 as our Anchorage router, R2 as our Fairbanks router, R4 and R5 will be random hosts on the internal LANs of R1 and R2 (respectively), and R3 will represent the Internet network between R1 and R2. Here is the basic configuration for R1 (the Anchorage router):

interface FastEthernet0/0
description LAN
ip address 192.168.1.1 255.255.255.0
ip nat inside
duplex auto
speed auto
!
interface FastEthernet1/0
description Inet
ip address 169.254.1.10 255.255.255.192
ip nat outside
duplex auto
speed auto
!
interface FastEthernet2/0
description OVPN to Fairbanks
ip address 172.16.1.1 255.255.255.252
ip nat inside
duplex auto
speed auto
!
ip nat inside source list 1 interface FastEthernet1/0 overload
no ip http server
no ip http secure-server
ip classless
ip route 0.0.0.0 0.0.0.0 169.254.1.1
!
access-list 1 permit 192.168.1.0 0.0.0.255
access-list 1 permit 172.16.1.0 0.0.0.3
!

As you can see, we have set up NAT to map addresses on the two internal interfaces to the external IP address of 169.254.1.10, and we have created a default route to the Internet router at 169.254.1.1. At this point, any hosts on the internal network should be able to reach any publicly-accessible IP address.

Similarly, here is the basic configuration for the Fairbanks router:

interface FastEthernet0/0
description LAN
ip address 192.168.3.1 255.255.255.0
ip nat inside
duplex auto
speed auto
!
interface FastEthernet1/0
description Inet
ip address 169.254.2.10 255.255.255.192
ip nat outside
duplex auto
speed auto
!
interface FastEthernet2/0
description OVPN to Anch
ip address 172.16.1.2 255.255.255.252
ip nat inside
duplex auto
speed auto
!
ip nat inside source list 1 interface FastEthernet1/0 overload
no ip http server
no ip http secure-server
ip classless
ip route 0.0.0.0 0.0.0.0 169.254.2.1
!
access-list 1 permit 192.168.3.0 0.0.0.255
access-list 1 permit 172.16.1.0 0.0.0.3
!

With this configuration, R4 should be able to ping the outside interface on R2, and R5 should be able to ping the outside interface on R1 (assuming that R3, R4 and R5 have been configured with the appropriate IP addresses on their respective interfaces, and that R4 and R5 have default routes through R1 and R2, respectively). However, if you try to ping R5 from R4 or vice versa, you will find that the pings fail, because R1 and R2 are not yet advertising routes to their internal networks. You could create static routes on these routers to solve this problem, but that's why we have dynamic routing protocols -- to reduce the network admin's workload.

However, you don't want to send routes to public IP addresses over your internal-only links, and even more importantly, you don't want to advertise your RFC-1918 IP addresses on the public Internet (your service provider should already be filtering these, but...). Therefore, we want to make sure OSPF is only advertising our private LAN addresses over the point-to-point link, so we'll create a route map on R1 and R2 to filter what routes OSPF advertises.

The first step in creating a route map is creating the access control list (ACL) to identify the traffic we want OSPF to allow. On R1...:

access-list 10 permit 192.168.3.0 0.0.0.255
access-list 10 permit 192.168.1.0 0.0.0.255
access-list 10 permit 172.16.1.0 0.0.0.3
!

...and on R2...:
access-list 10 permit 192.168.3.0 0.0.0.255
access-list 10 permit 192.168.1.0 0.0.0.255
access-list 10 permit 172.16.1.0 0.0.0.3
!

Note: If you don't fully understand the ACL's we have created here, check out CCNA Lesson 12 for a more in-depth explanation of ACL's on a Cisco router.

Next, we create the route-map to allow the networks filtered by these access lists (configuration is the same on both R1 and R2):
route-map inside-ospf permit 10
match ip address 10
!

Finally, we create our OSPF configuration, referencing the route maps. On R1:

router ospf 42
router-id 192.168.1.1
log-adjacency-changes
redistribute connected subnets route-map inside-ospf
network 172.16.1.0 0.0.0.3 area 0.0.0.0
!

...and on R2:

router ospf 42
router-id 192.168.3.1
log-adjacency-changes
redistribute connected subnets route-map inside-ospf
network 172.16.1.0 0.0.0.3 area 0.0.0.0
!


Here's what's happening in the router. We are creating the ACL to match our internal LAN traffic (192.168.1.0/24, 192.168.3.0/24, and 172.16.1.0/30). Then, we are creating a route map called "inside-ospf" to match the networks defined in ACL 10. Finally, OSPF is redistributing the networks referenced in the route-map "inside-ospf." If a network does not match the ACL, for example 169.254.1.0/26 (the network attached to fa1/0 on router R1), OSPF does not forward that route to other OSPF-enabled routers in that area. You can verify that this is working by tracing routes to various networks from R4 or R5. Here is an example of two traceroutes from R5:

Router#traceroute 192.168.1.2

Type escape sequence to abort.
Tracing the route to 192.168.1.2

1 192.168.3.1 8 msec 8 msec 8 msec
2 172.16.1.1 24 msec 8 msec 16 msec
3 192.168.1.2 28 msec 16 msec *
Router#traceroute 169.254.1.10

Type escape sequence to abort.
Tracing the route to 169.254.1.10

1 192.168.3.1 8 msec 4 msec 8 msec
2 169.254.2.1 16 msec 12 msec 8 msec
3 169.254.1.10 28 msec 25 msec *
Router#

You can see the traceroute follows the P-t-P link from R2 to R1 to reach 192.168.1.2, but follows the "Internet" link to reach the outside interface of R1, which is exactly what we wanted.

Reference:Cisco's "Route Maps for IP Routing Protocol Redistribution Configuration" web page.

Tuesday, June 3, 2014

Advanced Cisco Routing -- BGP and OSPF

If you wish to configure network gear for Service Provider networks, or even for Enterprise networks in large enough companies, you will eventually need to understand BGP. While I have worked for Service Providers for my entire professional career, I have never had the opportunity to work with BGP. However, due to some changes in my current work environment, I realized that I would need to come up to speed on BGP in the fairly near future, so I decided it was time to start playing with that particular routing protocol.

First, a little background. In my earlier Cisco and Juniper posts, we've discussed setting up and configuring OSPF, RIP, and EIGRP, so it might be reasonable to ask, what's so different about BGP? Without getting into too much detail, the bottom line is that the other routing protocols are designed for use within a single provider's network. You might have a lot of routers and a lot of routes, but the Internet's routing tables (for example) are much, much larger than your internal routing tables -- far too big, in fact, to fit on just about any router if you are using one of these protocols. BGP is the answer to this problem. It was designed to efficiently store and share very, very large routing tables on service provider networks. Consequently, you most often (but not exclusively!) see BGP on routers that are sharing publicly accessible routes on the Internet. It is important to note that BGP comes in two flavors: iBGP (internal BGP) that is used to share routes among your own networks, much like the routing protocols we have alread discussed; and eBGP (external BGP), which is used to share routes among other organizations. For this post, we will be discussing eBGP exclusively.

So, let's get started!

Here is the network that I created in GNS3:
Why GNS3 rather than a real hardware network? Well, first, I built this while at work (it was a slow day, and it is work-related learning), and second, because I have had to tear down my Cisco lab at home for reasons I'm sure you don't want to read about now :) Besides...I tried to get GNS3 to work a little while ago and failed, so I figured it was time to figure out how to make this puppy sing! It really wasn't all that difficult, but it did require some non-intuitive experimentation with settings until I got everything working.

Anyway, here's the description of the topology:

R1 and R2 are my core routers on this network -- they are the ones doing the BGP peering with each other. R1 is using AS64512 and R2 is using AS64513. Those AS numbers are not entirely random; they are, in fact, the first two private, reserved AS numbers according to the RFC's (think RFC-1918 for BGP autonomous system numbers, and you'll be pretty close). In GNS3, it doesn't really matter, but if you want to build BGP routers with real iron that might ever be connected to the Internet, you should probably use an AS number in the range 64512 - 65535 until/unless you get a real AS number from ARIN.

R3 and R4 are edge routers connected to R1; R5 and R6 are likewise edge routers connected to R2. R1, R3 and R4 make up the autonomous system in OSPF area 42. R2, R5 and R6 make up the autonomous system in OSPF area 51.

Finally, these are the networks connected to each router:
Router Interface IP Address Subnet Mask Description
R1 fa0/0 10.0.0.1 255.255.255.252 Uplink to R2
R1 fa1/0 192.168.1.1 255.255.255.0 Uplink to R3
R1 fa3/0 192.168.2.1 255.255.255.0 Uplink to R4
R2 fa0/0 10.0.0.2 255.255.255.252 Uplink to R1
R2 fa1/0 172.16.1.1 255.255.255.252 Uplink to R5
R2 fa2/0 172.16.20.1 255.255.255.252 Uplink to R6
R3 e0/0 192.168.10.1 255.255.255.0 LAN
R3 fa1/0 192.168.1.2 255.255.255.0 Uplink to R1
R4 e0/0 192.168.20.1 255.255.255.0 LAN
R4 fa1/0 192.168.2.2 255.255.255.0 Uplink to R1
R5 e0/0 172.16.10.1 255.255.255.0 LAN
R5 fa1/0 172.16.1.2 255.255.255.252 Uplink to R1
R6 e0/0 172.16.20.1 255.255.255.0 LAN
R6 fa1/0 172.16.2.2 255.255.255.252 Uplink to R1


I started by configuring OSPF on R1, R3 and R4:
R1#sho run | begin router ospf 42
router ospf 42
router-id 10.0.0.1
log-adjacency-changes
network 192.168.1.0 0.0.0.255 area 0
network 192.168.2.0 0.0.0.255 area 0
!

R3#sho run | begin router ospf 42
router ospf 42
router-id 192.168.10.1
log-adjacency-changes
redistribute connected subnets
network 192.168.1.0 0.0.0.255 area 0
!

R4#sho run | begin router ospf 42
router ospf 42
router-id 192.168.20.1
log-adjacency-changes
redistribute connected subnets
network 192.168.2.0 0.0.0.255 area 0
!

Once I had verified that I was routing between these three routers, I configured OSPF on R2, R5 and R6:
R2#sho run | begin ospf 51
router ospf 51
router-id 10.0.0.2
log-adjacency-changes
network 172.16.1.0 0.0.0.3 area 0
network 172.16.2.0 0.0.0.3 area 0
!

R5#sho run | begin ospf 51
router ospf 51
router-id 172.16.10.1
log-adjacency-changes
redistribute connected subnets
network 172.16.1.0 0.0.0.3 area 0
network 172.16.10.0 0.0.0.255 area 0
!

R6#sho run | begin router ospf 51
router ospf 51
router-id 172.16.20.1
log-adjacency-changes
redistribute connected subnets
network 172.16.2.0 0.0.0.3 area 0
network 172.16.20.0 0.0.0.255 area 0
!


...and checked to make sure that I had routing between these three routers, which I did.
Note: if any of this does not look familiar to you, I'd highly recommend you take a look at my blog entries on OSPF here and here to come up to speed on OSPF before digging into BGP.

Next, I configured the BGP routing process between R1 and R2:
R1#sho run | begin router bgp
router bgp 64512
bgp log-neighbor-changes
neighbor 10.0.0.2 remote-as 64513
address-family ipv4
neighbor 10.0.0.2 activate
no auto-summary
no synchronization
exit-address-family
!

R2#sho run | begin router bgp
router bgp 64513
bgp log-neighbor-changes
neighbor 10.0.0.1 remote-as 64512
address-family ipv4
neighbor 10.0.0.1 activate
no auto-summary
no synchronization
exit-address-family
!


First, note the AS numbers I mentioned earlier in the "router bgp..." command. In OSPF, we provide a process ID for the OSPF process; in BGP, we provide the AS number that we are advertising with BGP. We use those AS numbers on the very next line on the peer router to specify who we wish to be sharing routes with. Unlike OSPF, with BGP we specify the neighbor router(s) that we want to peer with. After that, we tell BGP what address family (IPv4, IPv6, etc.) that we will be advertising, and then we tell BGP to activate the peering session with our peer at <IP Address>. The rest of the lines were defaults automatically populated by IOS.

Unfortunately, at this point, I didn't see routes propagating between routers like I expected. After a little quality time with Google, I discovered that I hadn't told BGP what routes I wanted to share. Adding the line, "redistribute ospf 42 match internal external 1 external 2" on R1 and "redistribute ospf 51" on R2 solved that problem -- I was now able to see OSPF routes from the BGP peer showing up on R1 and R2.

Note: notice that R1 includes some extra syntax that R2 is missing on the "redistribute ospf..." statement. I don't have time right now to explain why that is necessary, but I'll try to add a post later to discuss what is different about the two networks.

However, all was not well in Mudville. When I got on the console for R6, I found that I could not ping R3 or R4. I ran "sho ip route" and found that, even though BGP had propagated routes from R1 onto R2 and vice versa, R2 hadn't shared those routes with R5 and R6, nor had R1 shared the routes learned through BGP with R3 and R4. That was because, even though I had told BGP to share OSPF routes (which it had), I hadn't told OSPF to share BGP routes! On R1, I added "redistribute bgp 64512 subnets" to the OSPF config, and on R2, I added "redistribute bgp 64513 subnets" which solved the problem. I could now ping any of the six routers from any of the five remaining routers.

Thursday, April 10, 2014

JNCIA -- Backing up Config Files

Okay, this is cool. You've set up your JunOS device (switch, router, whatever) just the way you want it, so you really should make a copy of the config so that, if the device ever fails, you can restore the configuration to replacement hardware with minimal effort (that whole, "the best sys admin is a lazy sys admin" thing again). Sure, after committing a config, you can always issue the commands to copy the config to an FTP server on your network, but, show of hands,...have you ever forgotten to do it? Look around -- everyone who didn't raise their hands is either very, very new to networking, or is lying ;)

Because we are all human, JunOS provides a very cool feature to work around the human limitation: a setting that dumps your config to an FTP server when you commit the config. Here's how you do it:

[edit]
root@branch-3200# edit system archival configuration

[edit system archival configuration]
root@branch-3200# transfer-on-commit;

[edit system archival configuration]
root@branch-3200# archive-sites {

[edit system archival configuration archive-sites]
"ftp://username:password@myftphost.example.com";


Of course, the ability to save your configuration is not terribly useful without the ability to restore it, so JunOS provides that ability, as well (natch):

[edit] root@branch-3200# edit system archival configuration

[edit system archival configuration]
root@branch-3200# load merge ftp://username:password@myftphost.example.com/branch-3200.conf.gz_20140410_111217

load complete

[edit system archival configuration]
root@branch-3200#