Showing posts with label basic configuration. Show all posts
Showing posts with label basic configuration. Show all posts

Monday, September 26, 2016

IPv6 Intro: Global Unicast Address, Link-Local Addresses, and a Brief Intro to Static Routing

In the last lab, we configured a link between R1 and R2, using the IP addresses "2001:co:ffee::4:1" and "2001:co:ffee::4:2," respectively.  Let's try something:
R1#sho ipv6 interface brief
FastEthernet0/0            [up/up]
    FE80::CE00:6BFF:FE8E:0
    2001:C0:FFEE::4:1
Loopback0                  [up/up]
    unassigned
R1#

Well, that's odd! I don't know about you, but I only recall configuring a single IPv6 address on Fa0/0 on R1, but the "sho ipv6 interface brief" command is displaying two addresses.

Actually, it's not odd at all. When you enable IPv6 on an interface, it automatically configures a special class of IPv6 addresses on the interface. Notice how the extra address begins with "FE80?" An IPv6 address that begins with FE80 is a "link-local" address, and they are automatically configured on every interface using IPv6. The IPv6 address that we manually added to the routers is called a "global unicast" address. At this point, you are probably wondering why we bothered to assign an IPv6 address to the interface if the router would automatically assign one, too. There's a hint buried within the names of these address types: "Link-local" and "global-unicast." "Link-local" addresses are locally scoped (where "locally" means local to that one interface), whereas "global-unicast" addresses are, well, globally-scoped. Try to ping the link-local address on R1 from R2:
R2#ping ipv6 fe80:0:0:0:ce00:6bff:fe8e:0
Output Interface: FastEthernet0/0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::CE00:6BFF:FE8E:0, timeout is 2 seconds:
Packet sent with a source address of FE80::CE01:6BFF:FE8E:0
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/16/36 ms
R2#

Interesting...notice how the router prompted you to specify an output interface? Since link-local addresses are locally-scoped to one specific interface, you have to specify which interface the ping command should use to reach the destination address. Just for giggles, let's add a new interface, Fa1/0, to R2, and connect a third router to that interface:



We'll add the new IPv6 addresses on both R2 and R3 as we've done in the past, and we'll add a static route so that R3 knows how to reach the 2001:co:ffee::4:0/126 network:
R3(config)#ipv6 route 2001:00c0:ffee:0:0:0:4:0/126 2015:0:0:0:0:0:0:1
R3(config)#exit
R3#ping ipv6 2001:00c0:ffee:0:0:0:4:2

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

Good! Let's add a static route for the link-local address on R2, Fa0/0:
R3(config)#ipv6 route fe80:0000:0000:0000:ce01:6bff:fe8e:0/126 2015:0:0:0:0:0:0:1
% Invalid prefix
R3(config)#

"Locally-scoped" means you can't route these addresses. The only place they are valid is on the interface directly connected to the destination address. Therefore, you can't create a static route for a link-local address. Let's try one more thing, just for the fun of it:



We'll configure the subnet 2001::0/125 on each of these interfaces:
R1(config-if)#int fa0/0
R1(config-if)#ipv6 addr 2001:0:0:0:0:0:0:1/125
R1(config-if)#no shut

R2(config-if)#int fa0/0
R2(config-if)#ipv6 addr 2001:0:0:0:0:0:0:2/125
R2(config-if)#no shut

R3(config-if)#int fa0/0
R3(config-if)#ipv6 addr 2001:0:0:0:0:0:0:3/125
R3(config-if)#no shut

Now, let's make sure each router can ping the other two routers:
R1#ping ipv6 2001:0:0:0:0:0:0:2

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

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

(I've omitted the output from R2 and R3 for the sake of brevity, but I did test them)

What about the link-local interfaces? Can we ping them? Let's find out:
R1#sho ipv6 int brie
FastEthernet0/0            [up/up]
    FE80::CE00:6BFF:FE8E:0
    2001::1
<...snip...>
R2#sho ipv6 int brie
FastEthernet0/0            [up/up]
    FE80::CE01:6BFF:FE8E:0
    2001::2
<...snip...>
R3#sho ipv6 int brie
FastEthernet0/0            [up/up]
    FE80::CE03:6BFF:FE8E:0
    2001::3
<...snip...>

Now that we have the link-local addresses on each router, we'll try the ping test:
R1#ping ipv6 FE80::CE01:6BFF:FE8E:0
Output Interface: FastEthernet0/0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::CE01:6BFF:FE8E:0, timeout is 2 seconds:
Packet sent with a source address of FE80::CE00:6BFF:FE8E:0
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/22/40 ms
R1#ping ipv6 FE80::CE03:6BFF:FE8E:0
Output Interface: FastEthernet0/0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::CE03:6BFF:FE8E:0, timeout is 2 seconds:
Packet sent with a source address of FE80::CE00:6BFF:FE8E:0
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/12/36 ms
R1#
<...snip...>

R2#ping ipv6 FE80::CE00:6BFF:FE8E:0
Output Interface: FastEthernet0/0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::CE00:6BFF:FE8E:0, timeout is 2 seconds:
Packet sent with a source address of FE80::CE01:6BFF:FE8E:0
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/5/8 ms
R2#ping ipv6 FE80::CE03:6BFF:FE8E:0
Output Interface: FastEthernet0/0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::CE03:6BFF:FE8E:0, timeout is 2 seconds:
Packet sent with a source address of FE80::CE01:6BFF:FE8E:0
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/10/20 ms
R2#
<...snip...>

R3#ping ipv6 FE80::CE00:6BFF:FE8E:0
Output Interface: FastEthernet0/0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::CE00:6BFF:FE8E:0, timeout is 2 seconds:
Packet sent with a source address of FE80::CE03:6BFF:FE8E:0
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/14/40 ms
R3#ping ipv6 FE80::CE01:6BFF:FE8E:0
Output Interface: FastEthernet0/0
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to FE80::CE01:6BFF:FE8E:0, timeout is 2 seconds:
Packet sent with a source address of FE80::CE03:6BFF:FE8E:0
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/15/36 ms
R3#
<...snip...>


As you can see, the link-local interface is not limited to point-to-point networks; it will also work on multipoint networks.

One other interesting point to raise about IPv6 addresses: there is no broadcast address, as there is in IPv4. Instead, IPv6 uses multicast to replicate the functionality of IPv4 broadcast addresses. In additon to global unicast, link-local and multicast addresses, IPv6 also supports a few other special classes of addresses, but we will save them for another day. With what we have covered in this lab and the previous lab, we now have enough grounding to start playing with routing...but I'll save that for the next lab.

IPv6 Intro: Address Format and Subnetting

A couple of years ago, I created a lab, Advanced Cisco Routing: Implementing OSPF in IPv6. I probably got the cart before the horse when I created that lab, since that was the only in this blog (so far) where we even discussed IPv6. Ideally, I should have given an intro to IPv6 addressing and networking before creating a lab where we implemented a routing protocol in IPv6. Today, I'd like to fix that problem. Let's start with a basic introduction to IPv6, from the beginning.

I won't spend a lot of time discussing the need for IPv6. If you are reading this blog, you are already well aware that we network types are quickly running out of free IPv4 addresses, and that in an increasingly connected world, we need to implement a new Layer-3 protocol in order to connect all of our devices to the public Internet. Good enough? ;) Good. Let's proceed with a description of IPv6.

Basic Format of an IPv6 Address:
In IPv4, a valid IP address is a 32-bit number, broken down into four groups of 8-bit numbers -- that is, four groups of digits, each of which can be in the range 0-255. For example, 10.254.254.1 is a valid IP address, as is 172.16.0.4 and 192.168.131.75. Technically, any grouping of octets from 0.0.0.0 to 255.255.255.255 would be valid for IP addressing. However, in practice, parts of the address space have been reserved for special purposes, and therefore, 224.0.0.0 through 255.255.255.255 are not usable for addressing hosts.

Because one of the primary drivers for IPv6 is a lack of IPv4 address space, an IPv6 address is rather more complex. Where IPv4 addresses are 32 bits in length, an IPv6 address is 128 bits in length. Where IPv4 addresses are typically written in decimal notation, IPv6 addresses are written in hexidecimal. Additionally, where an IPv4 address is divided into four groups of 8 bits, separated by a period ("."), IPv6 addresses are subdivided into eight groups of 16-bits each, separated by a colon (":"). For example:
2001:4840:af21:0000:0000:2112:2358:0042
fe80:0000:0000:0000:baca:8ffe:fe42:f138

Because hexidecimal numbers contain alphabetic characters between "A" and "F," you will often see IPv6 addresses with...ummm...clever (?)...words enmbedded in the addresses:
2016:00c0:ffee:4a11:0000:0000:0000:0001
2001:dead:beef:cafe:0000:0000:0000:0128

...which helps with memorizing frequently used addresses. Even better, if an address contains a long sequence of zeroes, you can abbreviate the IPv6 address by replacing the sequence with two colons (":"):
2016:00c0:ffee:4a11::0001

Actually, even that can be shortened, because it isn't necessary to include all of the leading zeroes in each 16-bit string, like so:
2016:c0:ffee:4a11::1

Note: This only applies to LEADING zeroes, however, because trailing zeroes are placeholders, and therefore are required! Consequently, you cannot shorten "2016:c0:ffee:4a11::1" any further, as the zero in "2016" and "c0" must be present. One other catch: you can only truncate sequences of zeroes ONCE in an IPv6 address. For example, if you had the complete IPv6 address, "2001:0000:0042:0000:0000:0000:0000:af41," you would have to choose which sequence of zeroes to truncate. These would be acceptable:
2001::42:0000:0000:0000:0000:af41
2001:0000:42::af41

...but this would not:
2001::42::af41

That is because with either of the first two examples, you can still determine where within the 128 bits of address the "42" lies, but "2001::42::af41" could be any of the following addresses:
2001:0000:0042:0000:0000:0000:0000:af41
2001:0000:0000:0042:0000:0000:0000:af41
2001:0000:0000:0000:0042:0000:0000:af41
2001:0000:0000:0000:0000:0042:0000:af41

Note: Wait a minute! When you abbreviated the full IPv6 address as "2001:0000:42::af41,", you dropped the two leading zeroes ahead of the "42" in "0042," even though you replaced all of the zeroes after "42!"

Yes, but since you can only drop the leading zeroes in a 16-bit segment (i.e., "0042" can be abbreviated as "42," but "4200" cannot), we still know exactly where it belongs in the full, expanded IPv6 address.

Subnetting:
Just as in IPv4, IPv6 addresses can be subnetted. Just as 10.254.254.1/32 is a host address in IPv4, 2001::192:168:1:1/128 is a host address in IPv6. You can subdivide networks in IPv6 to optimize the number of networks and hosts in exactly the same way that you would in IPv4. However, it is important to remember that IPv6 uses hexadecimal numbers, so if you decide to "encapsulate" a common IPv4 address in IPv6 as I did above, don't make the mistake of assuming that, for example, 2001::192:168:1:9/126 and 2001::192.168.1.10/126 are contiguous host addresses within the same subnet. They aren't, as I discovered in a lab recently ;) Between ":9" and ":10" in an IPv6 address, you will find ":a" through ":f" -- which spans two /126 subnets, with ":10" being the network address (as opposed to a host address) for yet another subnet!

Putting it into practice!
Let's create a lab in GNS3 (or actual hardware, if you'd prefer) where we start connecting devices with IPv6. We'll start with a very simple network consisting of two routers. For this first lab, all we'll do is enable IPv6 on the routers, apply an IPv6 address to the connected interfaces, and make sure we can ping across the connection:



Now, we'll turn up the IPv6 addresses on these two routers:
R1(config)#ipv6 unicast-routing
R1(config)#int fa0/0
R1(config-if)#ipv6 enable
R1(config-if)#ipv6 address 2001:00c0:ffee:0000:0000:0000:0004:0001/126
R1(config-if)#no shut
R1(config-if)#exit
R1(config#exit

...and on R2:
R2(config)#ipv6 unicast-routing
R2(config)#int fa0/0
R2(config-if)#ipv6 enable
R2(config-if)#ipv6 address 2001:00c0:ffee:0000:0000:0000:0004:0002/126
R2(config-if)#no shut
R2(config-if)#exit
R2(config#exit

Can we ping?
R1#ping ipv6 2001:00c0:ffee:0000:0000:0000:0004:0002

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:C0:FFEE::4:2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/19/36 ms
R1#

How about from R2?
R2#ping ipv6 2001:00c0:ffee:0000:0000:0000:0004:0001

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

Perfect! We have met the objectives of this lab, so we'll call it a day.

IPv6 Intro: Address Format and Subnetting

A couple of years ago, I created a lab, Advanced Cisco Routing: Implementing OSPF in IPv6. I probably got the cart before the horse when I created that lab, since that was the only in this blog (so far) where we even discussed IPv6. Ideally, I should have given an intro to IPv6 addressing and networking before creating a lab where we implemented a routing protocol in IPv6. Today, I'd like to fix that problem. Let's start with a basic introduction to IPv6, from the beginning.

I won't spend a lot of time discussing the need for IPv6. If you are reading this blog, you are already well aware that we network types are quickly running out of free IPv4 addresses, and that in an increasingly connected world, we need to implement a new Layer-3 protocol in order to connect all of our devices to the public Internet. Good enough? ;) Good. Let's proceed with a description of IPv6.

Basic Format of an IPv6 Address:
In IPv4, a valid IP address is a 32-bit number, broken down into four groups of 8-bit numbers -- that is, four groups of digits, each of which can be in the range 0-255. For example, 10.254.254.1 is a valid IP address, as is 172.16.0.4 and 192.168.131.75. Technically, any grouping of octets from 0.0.0.0 to 255.255.255.255 would be valid for IP addressing. However, in practice, parts of the address space have been reserved for special purposes, and therefore, 224.0.0.0 through 255.255.255.255 are not usable for addressing hosts.

Because one of the primary drivers for IPv6 is a lack of IPv4 address space, an IPv6 address is rather more complex. Where IPv4 addresses are 32 bits in length, an IPv6 address is 128 bits in length. Where IPv4 addresses are typically written in decimal notation, IPv6 addresses are written in hexidecimal. Additionally, where an IPv4 address is divided into four groups of 8 bits, separated by a period ("."), IPv6 addresses are subdivided into eight groups of 16-bits each, separated by a colon (":"). For example:
2001:4840:af21:0000:0000:2112:2358:0042
fe80:0000:0000:0000:baca:8ffe:fe42:f138

Because hexidecimal numbers contain alphabetic characters between "A" and "F," you will often see IPv6 addresses with...ummm...clever (?)...words enmbedded in the addresses:
2016:00c0:ffee:4a11:0000:0000:0000:0001
2001:dead:beef:cafe:0000:0000:0000:0128

...which helps with memorizing frequently used addresses. Even better, if an address contains a long sequence of zeroes, you can abbreviate the IPv6 address by replacing the sequence with two colons (":"):
2016:00c0:ffee:4a11::0001

Actually, even that can be shortened, because it isn't necessary to include all of the leading zeroes in each 16-bit string, like so:
2016:c0:ffee:4a11::1

Note: This only applies to LEADING zeroes, however, because trailing zeroes are placeholders, and therefore are required! Consequently, you cannot shorten "2016:c0:ffee:4a11::1" any further, as the zero in "2016" and "c0" must be present. One other catch: you can only truncate sequences of zeroes ONCE in an IPv6 address. For example, if you had the complete IPv6 address, "2001:0000:0042:0000:0000:0000:0000:af41," you would have to choose which sequence of zeroes to truncate. These would be acceptable:
2001::42:0000:0000:0000:0000:af41
2001:0000:42::af41

...but this would not:
2001::42::af41

That is because with either of the first two examples, you can still determine where within the 128 bits of address the "42" lies, but "2001::42::af41" could be any of the following addresses:
2001:0000:0042:0000:0000:0000:0000:af41
2001:0000:0000:0042:0000:0000:0000:af41
2001:0000:0000:0000:0042:0000:0000:af41
2001:0000:0000:0000:0000:0042:0000:af41

Note: Wait a minute! When you abbreviated the full IPv6 address as "2001:0000:42::af41,", you dropped the two leading zeroes ahead of the "42" in "0042," even though you replaced all of the zeroes after "42!"

Yes, but since you can only drop the leading zeroes in a 16-bit segment (i.e., "0042" can be abbreviated as "42," but "4200" cannot), we still know exactly where it belongs in the full, expanded IPv6 address.
Subnetting:
Just as in IPv4, IPv6 addresses can be subnetted. Just as 10.254.254.1/32 is a host address in IPv4, 2001::192:168:1:1/128 is a host address in IPv6. You can subdivide networks in IPv6 to optimize the number of networks and hosts in exactly the same way that you would in IPv4. However, it is important to remember that IPv6 uses hexadecimal numbers, so if you decide to "encapsulate" a common IPv4 address in IPv6 as I did above, don't make the mistake of assuming that, for example, 2001::192:168:1:9/126 and 2001::192.168.1.10/126 are contiguous host addresses within the same subnet. They aren't, as I discovered in a lab recently ;) Between "::9" and "::10" in an IPv6 address, you will find "::a" through "::f" -- which spans two /126 subnets, with "::10" being the network address for a third!

Putting it into practice!
Let's create a lab in GNS3 (or actual hardware, if you'd prefer) where we start connecting devices with IPv6. We'll start with a very simple network consisting of two routers. For this first lab, all we'll do is enable IPv6 on the routers, apply an IPv6 address to the connected interfaces, and make sure we can ping across the connection:



Now, we'll turn up the IPv6 addresses on these two routers:
R1(config)#ipv6 unicast-routing
R1(config)#int fa0/0
R1(config-if)#ipv6 enable
R1(config-if)#ipv6 address 2001:00c0:ffee:0000:0000:0000:0004:0001/126
R1(config-if)#no shut
R1(config-if)#exit
R1(config#exit

...and on R2:
R2(config)#ipv6 unicast-routing
R2(config)#int fa0/0
R2(config-if)#ipv6 enable
R2(config-if)#ipv6 address 2001:00c0:ffee:0000:0000:0000:0004:0002/126
R2(config-if)#no shut
R2(config-if)#exit
R2(config#exit
>
Can we ping?
R1#ping ipv6 2001:00c0:ffee:0000:0000:0000:0004:0002

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:C0:FFEE::4:2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/19/36 ms
R1#

How about from R2?
R2#ping ipv6 2001:00c0:ffee:0000:0000:0000:0004:0001

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

Perfect! We have met the objectives of this lab, so we'll call it a day.

Friday, August 29, 2014

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#

Tuesday, November 12, 2013

JNCIA Lesson 7 -- DHCP

It is, perhaps, a little unfair that for many of these labs, I have been cheating slightly.

Don't get me wrong; I have configured all of the protocols and examples that we have discussed, and I have verified that the examples I have provided work as advertised. However, many of these examples have required that we connect one or more hosts to the various networks that we have built so that we can test end-to-end connectivity across the network(s). While there is certainly no reason why a network admin cannot configure such hosts by hand, I must confess that I do not like doing more work than is necessary. Again, do not be mislead; I am not claiming that I am unwilling to work when it is necessary, but rather I am saying that if there is an easy way to accomplish a task and a difficult way to accomplish a task, then, all else being equal, I will choose the easy way. To that end, when I have needed a PC connected to the Juniper switches to test connectivity, I have -- without providing you with the instructions on how to do likewise -- made use of the DHCP protocol to automatically assign IP addresses to my devices. I apologize, and in penance, I will endeavour to right that wrong in this lesson ;)

As I am sure you know -- or at least have by now guessed -- DHCP is a standard protocol for automatically assigning various network settings to computers on a LAN. Most obvious, of course, is the ability to automatically assign an IP address to a host on the network. However, DHCP can also assign a number of other settings such as the default gateway, DNS (name server) addresses, and domain name. Needless to say, the ability to automatically provision network settings to any device that connects to a LAN can be a huge time-saver for a busy network admin. Do you really want to visit the workstation of every user in your company first thing in the morning to assign an IP address for the day? Of course, not! Fortunately, this is another example of the kind of routine, mundane, repetitive task that computers perform extremely well, so let's set up our main office EX3200 to do so.

In one of the earlier lessons, we agreed that the default VLAN on our main3200 switch would use the network 192.168.1.0/24. However, we also stated that we would have a handful of network devices and servers on this network. Network devices almost always have their IP addresses assigned statically, as it becomes very difficult to configure your LAN equipment to reach a default gateway, for example, when the gateway address changes periodically. Servers, for exactly the same reason, often have statically assigned IP addresses also, and therefore, we will set aside the first 15 IP addresses -- 192.168.1.1 through 192.168.1.15 -- for servers and network equipment. Consequently, our DHCP server will assign addresses in the range 192.168.1.16 through 192.168.1.254 to client PCs. Also, our DNS servers for all three networks are located at 192.168.1.6 and 192.168.2.6; we'll assign those name server addresses to client PC's, as well. Let's get started:

root@main3200# edit system services

[edit system services]
root@main3200# set dhcp domain-name main.example.com

[edit system services]
root@main3200# set dhcp router 192.168.1.1

[edit system services]
root@main3200# set dhcp pool 192.168.1.0/24 address-range low 192.168.1.16 high 192.168.1.254

[edit system services]
root@main3200# set dhcp name-server 192.168.1.6

[edit system services]
root@main3200# set dhcp name-server 192.168.2.6

[edit system services]
root@main3200# commit
commit complete

[edit system services]
root@main3200#


That's it!

Now, hook up a PC to one of the ports in the default VLAN, and see if it obtains an address in the 192.168.1.0/24 net block:

me@myllt:~$ ip addr | egrep -A3 "eth0:"
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:24:e8:cb:f9:e9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.16/24 brd 192.168.1.255 scope global eth0
    inet6 fd04:4879:556a:0:24:e8ff:fecb:f9e9/64 scope global
me@myllt:~$


Sweet! My laptop obtained the IP address 192.168.1.16/24 automatically from the DHCP service on the EX3200 switch!

However, we still have a problem. If you recall, we had planned not just one, but two VLANs on this physical network: the default VLAN for hosts like my laptop, but also a Voice-over-IP VLAN for our internal PBX. It's nice not to have to statically assign IP addresses to desktops and laptops, but wouldn't it be nice to also have DHCP hand off IP addresses automatically to the VoIP telephones, too?

Fortunately, that's not a problem, either. All we have to do is set up a separate DHCP pool using the same net block that we put the VoIP VLAN into:

root@main3200# set dhcp router 192.168.10.1

[edit system services]
root@main3200# set dhcp pool 192.168.10.0/24 address-range low 192.168.10.8 high 192.168.10.254

[edit system services]
root@main3200# set dhcp sip-server address 192.168.10.2

[edit system services]
root@main3200# commit
commit complete

[edit system services]
root@main3200#


Now, to test, we'll connect another laptop to one of the ports in the VoIP VLAN and see if we get a 192.168.10.xxx address:

me@myllt2:~$ ip addr | egrep -A3 "eth0:"
2: eth0: mtu 1500 qdisc mq state UP qlen 1000
    link/ether 00:15:c5:08:5d:92 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.8/24 brd 192.168.10.255 scope global eth0
    inet6 fd04:4879:556a:0:15:c5ff:fe08:5d92/64 scope global
me@myllt2:~$


Yep, it worked! We now have both the default VLAN and the VoIP VLAN receiving IP addresses automatically.

It's outside of the scope of this lesson, but just for grins, let's see if OSPF will route across the VLANs for us:

me@myllt2:~$ ping -c1 192.168.1.16
PING 192.168.1.16 (192.168.1.16) 56(84) bytes of data.
64 bytes from 192.168.1.16: icmp_req=1 ttl=63 time=1.82 ms

--- 192.168.1.16 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.822/1.822/1.822/0.000 ms
me@myllt2:~$


There's that "routing-on-a-stick" we discussed earlier in action for ya' ;)

JNCIA Lesson 6 -- Spanning Tree, Rapid Spanning Tree and Multiple Spanning Tree

In our network design, we have two EX3200 switches at the main office, connected through a single copper cross-over cable. A savvy network administrator would probably look at our design and ask, "What would happen if either Ethernet port, or more likely, the Ethernet cable itself were to fail?" The link from our main3200 switch to our main2-3200 switch is indeed a single point of failure on our network. Many a junior network admin have had the sudden realization that such a design is a problem waiting to happen, and in their eagerness to show how pro-active and fore-sighted they are, have then run a second Ethernet cable between the two switches in order to create a redundant connection between them.

If the junior admin was lucky, (s)he probably just spent a while wondering why one of the redundant Ethernet ports suddenly went off-line (had a customer do that to me once, on a Metro-Ethernet ring, in fact). If the junior admin was not so lucky, however, (s)he created a broadcast storm, crashing the entire Layer-2 network with (her)his well-intentioned, but naive, blunder:



In actual practice, the diagrams above are an over-simplification: if Switch A was actually sending a broadcast, it would have forwarded the frame out the ports to *both* Switch B and Switch C, and both Switch B and Switch C would have forwarded the broadcast frame to each other, resulting in multiple copies of the same frame circulating through the network simultaneously. In fact, if there are four or more switches in the network connected in a full-mesh network, then with every cycle there are more and more frames circulating through the network until the switches can no longer keep up with traffic (with three or less switches, the number of frames circulating won't grow, since the switches will not forward a broadcast back out the interface upon which it was received).

In our example with the junior admin, (her)his instincts were good; the network, as originally designed, was vulnerable to failure, and it would be a good idea to design a redundant path between switches, if there were a way to prevent such loops from occurring. Fortunately, this is exactly the type of problem that the Spanning Tree protocol (STP), and it's later refinements, Rapid Spanning Tree (RSTP) and Muliple Spanning Tree (MSTP), were designed to solve.

The method through with STP prevents loops is quite simple: essentially, the protocol just shuts down redundant network ports until/unless the switches in the tree detect a failure on an active port. In our example above, and assuming that Switch A was the "root bridge" (we'll define that term shortly), Spanning Tree (or RSTP or MSTP) would put one of the ports on either Switch B or Switch C into a "blocking" state, thus breaking the loop. Now, if Switch A sends a broadcast frame to Switches B and C, they will each forward the packet to devices connected to their switch ports, but NOT to each other.

This (simplified) explanation of Spanning Tree raises an important question: how do the switches determine if there is a loop, or if there is a network port which needs to be shut down? When a switch (or group of switches) is first powered on, it sends a query out each of its enabled switch ports, called a "Bridge Protocol Data Unit." Routers and PCs ignore the BPDU, but other switches examine the BPDU to check for loops in the layer-2 topology. Some of the data transferred during this process is used to elect a "root bridge" -- the switch that will be the pinnacle of the spanning tree network. As we've already stated, spanning tree will shut down ports to break loops in the layer-2 network, but the root bridge is special: all enabled ports on the root bridge always remain active. On any switches with a single port connected to the root bridge, those ports will also always remain active, and are known as "root ports." If there are multiple ports to the root bridge, the switch will select a single port as a root port, and shut down the rest. Any ports that spanning tree uses to reach other switches, but which do not provide a path for that switch to reach the root bridge will are called "designated ports." Confused yet? Let's look a drawing to try to make it a little clearer:



As you can see, all of the switch ports that are directly connected to Switch A are root ports, all of the switch ports in a forwarding state that are NOT directly connected to Switch A are designated ports, and the ports in a blocking state are non-designated ports.

One other question that might come to mind at this point is, "how do the switches determine which switch is the root bridge?" Spanning Tree uses two metrics for electing a root bridge: first, the admin can set a value known as "root bridge priority" when configuring spanning tree, and lowest priority wins; second, if two or more switches have the same priority, then the switch with the lowest MAC address wins. In JunOS, the root bridge priority and MAC address are concatenated into a single value known as the "root ID" which can be shown with the "show spanning-tree bridge" command:

root@main3200# run show spanning-tree bridge

STP bridge parameters
Context ID                          : 0
Enabled protocol                    : RSTP
<...snip...>
  Local parameters
    Bridge ID                       : 32768.3c:8a:b0:99:df:c1
<...snip...>
root@main3200#


As you can see, the root ID on this switch is 32768.3c:8a:b0:99:df:c1. Suppose we had two other switches in a full-mesh, layer-2 network, and the other switches had root ID's of 32768.3c:8a:b0:99:e5:41 and 32768.3c:8a:b0:9a:22:01. Which switch would be elected root bridge? Let's connect these three switches together and find out! I'll connect ge-0/0/23 on the first switch to ge-0/0/22 on the second switch, connect ge-0/0/23 on the second switch to ge-0/0/22 on the third switch, then connect ge-0/0/23 on the third switch to ge-0/0/22 on the first switch. Once the switches are wired up to create a loop at layer-2, we'll re-run the "show spanning-tree bridge" command and see which switch was actually elected to be the root bridge:

root@main3200# run show spanning-tree bridge | match "Root ID"
  Root ID                           : 32768.3c:8a:b0:99:df:c1

[edit]
root@main3200#


root@branch1-3200# run show spanning-tree bridge | match "Root ID"
  Root ID                           : 32768.3c:8a:b0:99:df:c1

[edit]
root@branch1-3200#


root@branch2-3200# run show spanning-tree bridge | match "Root ID"
  Root ID                           : 32768.3c:8a:b0:99:df:c1

[edit]
root@branch2-3200#


Since all three switches have the same priority (JunOS' default of 32768), the election was determined by the lowest MAC address, which belongs to main3200.

If we wanted to know which ports were shut down, we would use the "show spanning-tree interface" command, but here, I have to make an admission: I couldn't actually find enough cross-over cables to connect all three switches in a full-mesh network, so I had to disconnect branch2-3200 for the following portion of the lab:

root@main3200# run show spanning-tree interface

Spanning tree interface parameters for instance 0

Interface    Port ID    Designated      Designated         Port    State  Role
                         port ID        bridge ID          Cost
ge-0/0/22.0    128:535      128:535  32768.3c8ab099dfc1     20000  FWD    DESG
ge-0/0/23.0    128:536      128:536  32768.3c8ab099dfc1     20000  FWD    DESG

[edit]
root@main3200#


root@branch1-3200# run show spanning-tree interface

Spanning tree interface parameters for instance 0

Interface    Port ID    Designated      Designated         Port    State  Role
                         port ID        bridge ID          Cost
ge-0/0/22.0    128:535      128:536  32768.3c8ab099dfc1     20000  BLK    ALT
ge-0/0/23.0    128:536      128:535  32768.3c8ab099dfc1     20000  FWD    ROOT

[edit]
root@branch1-3200#


If you notice, ge-0/0/22 on branch1-3200 is blocked by Spanning Tree, which shows that, when a link between two switches is determined to be redundant, if the path-cost back to the root bridge is equal, the lowest port number will be shut down (however, you can manually assign a port-cost to bias for or against a particular port, if you want).

RSTP is enabled on Juniper EX-series switches by default, but if you need to manually configure Spanning Tree, Rapid Spanning Tree or Multiple Spanning Tree, it's a very easy process. All three protocols are configured in exactly the same way, with just a couple of exceptions, which we'll cover in just a minute. Consequently, we'll only run through the configuration steps once, using RSTP. If you are using STP or MSTP, then rather than using "edit protocols rstp" (or "set protocols rstp ..."), you will use "edit protocols stp" or "edit protocols mstp" as appropriate.

First, we'll set the bridge priority to be lower on branch1-3200, to make it the root bridge instead of main3200:

root@branch1-3200# edit protocols rstp

[edit protocols rstp]
root@branch1-3200# set bridge-priority 20k

[edit protocols rstp]
root@branch1-3200#


Next, we will disable RSTP on ge-0/0/12.0 and commit the config:
root@branch1-3200# set interface ge-0/0/12.0 disable

[edit protocols rstp]
root@branch1-3200# commit
commit complete

[edit protocols rstp]
root@branch1-3200#


Now, one of the ports on main3200 should be in the blocking state, rather than on branch1-3200:

root@main3200# run show spanning-tree interface

Spanning tree interface parameters for instance 0

Interface    Port ID    Designated      Designated         Port    State  Role
                         port ID        bridge ID          Cost
ge-0/0/22.0    128:535      128:536  20480.3c8ab099e541     20000  BLK    ALT  
ge-0/0/23.0    128:536      128:535  20480.3c8ab099e541     20000  FWD    ROOT

[edit protocols rstp]
root@main3200#


...and sure enough, ge-0/0/22.0 on main3200 is now in the blocking state. Let's adjust the priority to put ge-0/0/23 in the blocking state, instead:

root@main3200# set interface ge-0/0/22 cost 1000

[edit protocols rstp]
root@main3200# commit
commit complete

[edit protocols rstp]
root@main3200# run show spanning-tree interface

Spanning tree interface parameters for instance 0

Interface    Port ID    Designated      Designated         Port    State  Role
                         port ID        bridge ID          Cost
ge-0/0/22.0    128:535      128:536  20480.3c8ab099e541      1000  FWD    ROOT
ge-0/0/23.0    128:536      128:535  20480.3c8ab099e541     20000  BLK    ALT  

[edit protocols rstp]
root@main3200#


One of the problems with spanning tree is the time it takes for the network to "converge" -- that is, the time it takes for the switches to elect a root bridge, determine if there are any loops in the topology, and then to shut down any redundant links. In STP, convergence can take almost a full minute, which is at least part of the reason RSTP was created. While RSTP is already quicker to converge than STP, it can converge even quicker if point-to-point links are declared as such with the "set protocols rstp interface ge-0/0/<whatever> mode point-to-point" command (Edit: if you are confused here, you are not alone. I'm not sure what a "point-to-point" link even means in a layer-2 network, but if I find out, I'll notate it here).

MSTP also differs from standard STP configuration in that you must add two more lines to the config:

root@main3200# set protocols mstp configuration-name jncia-example-1

[edit]
root@main3200# set protocols mstp msti 1 vlan [ 1 2 4 ]

[edit]
root@main3200# set protocols mstp msti 2 vlan [ 3 5 6 20 ]

[edit]
root@main3200#
<...etc...>


The only "gotcha" when putting VLANs into an MSTP instance (MSTI) is that every VLAN in a given instance must share a common topology.

Monday, November 11, 2013

JNCIA Lesson 5 -- VLANs

Up to this point, there has been an "elephant in the room" that we've carefully been sidestepping around. So far, many of our configs have referenced VLANs and Juniper's related -- but significantly different -- concept of "units." Today, we'll dig into VLANs and try to figure out exactly what they are and how to use them. We'll start with a common problem in networking that will hopefully illustrate the use and power of VLANs, then implement a solution for this problem in JunOS.

Suppose you have built a data network for your organization using standard Layer-2-only switches. Shortly afterwards, your internal PBX catastrophically fails beyond any hope of recovery. You decide that continuing to use antiquated POTS telephony is a poor idea, and instead, decide to implement an Asterisk open-source, voice-over-IP (VoIP) PBX system instead. Having done your homework, you are well aware of the common pitfalls associated with VoIP services -- such as Quality of Service (QoS), latency and jitter -- and therefore, you want to roll out the PBX on an entirely new network to minimize contention with other network consumers. However, it seems wasteful to buy additional switches for your enterprise, when you've already got unused ports on the switches you already have in use.

If only there were some way to logically separate the switch ports into separate networks, so that data users would only be in contention with each other for bandwidth while VoIP users could be on their own low-latency network...

Fortunately, this is exactly what VLANs were created to do. VLANs are a logical separation of two (or more) networks using the physical hardware of only one network. Remember when you were a kid and had to share a bedroom with brother or sister? Did you ever get into a fight with your sibling, and draw a line down the middle of the room, declaring something to the effect of, "This is my half of the room, and that is your half. Keep out of my half of the room!" That's basically all a VLAN does -- it splits the switch into separate broadcast domains so that traffic on one virtual LAN (VLAN) does not interact with traffic from other VLANs.

There are two ways for this split to occur, and typically, both methods will be used. First, you can separate the VLANs by port -- ports 1, 5, and 18-24 all belong to VLAN 10, while the remaining ports belong to VLAN 20, for example -- or you can separate traffic into separate VLANs by adding a tag into the Ethernet frame to mark certain frames as belonging to one VLAN and other frames as belonging to another VLAN. Each frame can belong to one and only one VLAN; there is no way to define a frame as belonging to multiple VLANs. Generally speaking, if the port will be connected to a client device -- a desktop, laptop, VoIP telephone, etc. -- you will define the VLAN by port, what is often referred to as an "untagged" or "access" VLAN port. On the other hand, if the port will be used to connect another network device, such as another switch or a router or sometimes even a server -- in other words, any time you potentially want more than one VLAN to transit an Ethernet link -- you will "tag" the frames coming from that port, creating a "tagged" or "trunk" port.

Let's take the example of the VoIP network and look at how we would implement such a design on the EX3200 switches. We've decided to use ports 0-7 on each EX3200 switch for the VoIP service because these ports support Power over Ethernet (PoE), which we can use to power the VoIP telephones (we'll just accept that statement as-is for the time being, as a full discussion of PoE is beyond the scope of this discussion). Additionally, we'll need a port for the Asterisk server, so we will add ge-0/0/8 to the VoIP VLAN, as well. We'll start the configuration by defining the Voice over IP VLAN on the switches:

root@main3200# edit vlans

[edit vlans]
root@main3200# set voip vlan-id 20

[edit vlans]
root@main3200#


Next, we need to define the VLAN interface:

root@main3200# top edit interfaces

[edit interfaces]
root@main3200# set vlan unit 20

[edit interfaces]
root@main3200#


If we wanted this VLAN to be routed, this is where we would add a Layer-3 address to the VLAN interface. Since we have three offices connected over a Layer-3 network, let's go ahead and add the IP address 192.168.10.1/24 to the main3200 router:

root@main3200# delete vlan unit 20 family ethernet-switching

[edit interfaces]
root@main3200# set vlan unit 20 family inet address 192.168.10.1/24

[edit interfaces]
root@main3200#


Now that we have defined the VLANs and the virtual interfaces through which the EX3200 will communicate, we'll need to assign these VLANs to the Gigabit Ethernet ports on the switch. The default VLAN is assigned to each switchport by, well, default. Therefore, we'll only need to add VLAN 20 the Ethernet ports that are used by the VoIP phones and PBX. We've already decided to put ge-0/0/0 through ge-0/0/8 into the VoIP VLAN, so let's make it so:

root@main3200# top

[edit]
root@main3200# set interfaces ge-0/0/0 unit 0 family ethernet-switching vlan members voip

[edit]
root@main3200# set interfaces ge-0/0/1 unit 0 family ethernet-switching vlan members voip

[edit]
root@main3200# set interfaces ge-0/0/2 unit 0 family ethernet-switching vlan members voips

[edit]
root@main3200# set interfaces ge-0/0/3 unit 0 family ethernet-switching vlan members voip

[edit]
root@main3200# set interfaces ge-0/0/4 unit 0 family ethernet-switching vlan members voip

[edit]
root@main3200# set interfaces ge-0/0/5 unit 0 family ethernet-switching vlan members voip

[edit]
root@main3200# set interfaces ge-0/0/6 unit 0 family ethernet-switching vlan members voip

[edit]
root@main3200# set interfaces ge-0/0/7 unit 0 family ethernet-switching vlan members voip

[edit]
root@main3200# set interfaces ge-0/0/8 unit 0 family ethernet-switching vlan members voip

[edit]
root@main3200# commit
commit complete

[edit]
root@main3200#


We now have nine Ethernet ports, ge-0/0/0 through ge-0/0/8 in the "voip" VLAN (VLAN 20). You hook up Linux hosts to two of the ports, connect a third Linux host to ge-0/0/10 (in the "default" VLAN), configure all of their IP addresses to all be in the 192.168.1.0/24 subnet, and start testing. As expected, hosts on ge-0/0/0 through ge-0/0/8 can talk to each other, but the host on ge-0/0/10 cannot reach either of the other two hosts, since it is in a different VLAN:

root@ge-0-0-2:/root# ping 192.168.1.238
PING 192.168.1.238 (192.168.1.238) 56(84) bytes of data.
64 bytes from 192.168.1.238: icmp_seq=1 ttl=64 time=0.436 ms
64 bytes from 192.168.1.238: icmp_seq=2 ttl=64 time=0.241 ms
64 bytes from 192.168.1.238: icmp_seq=3 ttl=64 time=0.234 ms
64 bytes from 192.168.1.238: icmp_seq=4 ttl=64 time=0.212 ms

--- 192.168.1.238 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.212/0.280/0.436/0.092 ms
root@ge-0-0-2:/root#
...
root@ge-0-0-10:~# nmap -sP 192.168.1.0/24

Starting Nmap 6.00 ( http://nmap.org ) at 2013-10-25 11:09 AKDT
Nmap scan report for 192.168.1.134
Host is up.
Nmap done: 256 IP addresses (1 host up) scanned in 11.12 seconds
root@ge-0-0-10:~# ip addr | egrep eth0 | egrep inet
inet 192.168.1.134/24 brd 192.168.1.255 scope global eth0
root@ge-0-0-10:~#
...
root@ge-0-0-6:~# ping -c4 192.168.1.134
PING 192.168.1.134 (192.168.1.134) 56(84) bytes of data.
From 192.168.1.238 icmp_seq=1 Destination Host Unreachable
From 192.168.1.238 icmp_seq=2 Destination Host Unreachable
From 192.168.1.238 icmp_seq=3 Destination Host Unreachable
From 192.168.1.238 icmp_seq=4 Destination Host Unreachable

--- 192.168.1.134 ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3014ms
root@ge-0-0-6:~# ping -c4 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_req=1 ttl=64 time=1.96 ms
64 bytes from 192.168.1.1: icmp_req=2 ttl=64 time=0.176 ms
64 bytes from 192.168.1.1: icmp_req=3 ttl=64 time=0.164 ms
64 bytes from 192.168.1.1: icmp_req=4 ttl=64 time=0.165 ms

--- 192.168.1.1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 0.164/0.617/1.965/0.778 ms
root@ge-0-0-6:~#


Perfect! Now, let's see if we can get ge-0/0/23 configured to do 802.1q tagging so we can use it as an uplink port from the second switch in the Main Office LAN:

root@main3200# edit interfaces ge-0/0/23 unit 0 family ethernet-switching

[edit interfaces ge-0/0/23 unit 0 family ethernet-switching]
root@main3200# set port-mode trunk

[edit interfaces ge-0/0/23 unit 0 family ethernet-switching]
root@main3200# set vlan members 20

[edit interfaces ge-0/0/23 unit 0 family ethernet-switching]
root@main3200# set native-vlan-id default

[edit interfaces ge-0/0/2 unit 0 family ethernet-switching]
root@main3200# commit
commit complete

[edit interfaces ge-0/0/2 unit 0 family ethernet-switching]
root@main3200#


Now, connect a cross-over cable between the two switches, and connect two hosts to each switch, one host (per switch) on ge-0/0/2 and one host (per switch) on ge-0/0/10. First we'll try pinging from a PC in the default VLAN on the first switch (main3200, ge-0/0/10) to all three other hosts:

root@mo-ge-0-0-10# ping -c4 mo2-ge-0-0-10.example.com
PING mo2-ge-0-0-10.example.com (192.168.1.134) 56(84) bytes of data.
64 bytes from 192.168.1.134: icmp_seq=1 ttl=64 time=0.590 ms
64 bytes from 192.168.1.134: icmp_seq=2 ttl=64 time=0.383 ms
64 bytes from 192.168.1.134: icmp_seq=3 ttl=64 time=0.363 ms
64 bytes from 192.168.1.134: icmp_seq=4 ttl=64 time=0.392 ms

--- mo2-ge-0-0-10.example.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.363/0.432/0.590/0.091 ms
root@mo-ge-0-0-10/root# ping -c4 mo-ge-0-0-2.example.com
PING mo-ge-0-0-2.example.com (192.168.1.17) 56(84) bytes of data.
From 192.168.1.250 icmp_seq=1 Destination Host Unreachable
From 192.168.1.250 icmp_seq=2 Destination Host Unreachable
From 192.168.1.250 icmp_seq=3 Destination Host Unreachable
From 192.168.1.250 icmp_seq=4 Destination Host Unreachable

--- mo-ge-0-0-2.example.com ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 2999ms, pipe 3
root@mo-ge-0-0-10:/root# ping -c4 mo2-ge-0-0-2.example.com
PING mo2-ge-0-0-2.example.com (192.168.1.129) 56(84) bytes of data.
From 192.168.1.250 icmp_seq=1 Destination Host Unreachable
From 192.168.1.250 icmp_seq=2 Destination Host Unreachable
From 192.168.1.250 icmp_seq=3 Destination Host Unreachable
From 192.168.1.250 icmp_seq=4 Destination Host Unreachable

--- mo2-ge-0-0-2.example.com ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 2999ms, pipe 3
root@mo-ge-0-0-10:/root#


Exactly what I expected to see: the host on switch one, port ge-0/0/10 can ping the host on switch two, port ge-0/0/10, but cannot ping the hosts on ge-0/0/2 on either switch. Perfect! Let's make sure the hosts on ge-0/0/2 can ping each other but not hosts on ge-0/0/10:

root@mo-ge-0-0-2:/root# ping -c4 mo2-ge-0-0-10
PING mo2-ge-0-0-10 (192.168.1.134) 56(84) bytes of data.
From 192.168.1.17 icmp_seq=1 Destination Host Unreachable
From 192.168.1.17 icmp_seq=2 Destination Host Unreachable
From 192.168.1.17 icmp_seq=3 Destination Host Unreachable
From 192.168.1.17 icmp_seq=4 Destination Host Unreachable

--- mo2-ge-0-0-10 ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 2999ms pipe 4
root@mo-ge-0-0-2:/root# ping -c4 mo2-ge-0-0-2
PING mo2-ge-0-0-2 (192.168.1.129) 56(84) bytes of data.
64 bytes from 192.168.1.129: icmp_req=1 ttl=64 time=0.509 ms
64 bytes from 192.168.1.129: icmp_req=2 ttl=64 time=0.233 ms
64 bytes from 192.168.1.129: icmp_req=3 ttl=64 time=0.247 ms
64 bytes from 192.168.1.129: icmp_req=4 ttl=64 time=0.283 ms

--- mo2-ge-0-0-2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2997ms
rtt min/avg/max/mdev = 0.233/0.318/0.509/0.111 ms
root@mo-ge-0-0-2:/root# ping -c4 mo-ge-0-0-10
PING mo-ge-0-0-10 (192.168.1.250) 56(84) bytes of data.
From 192.168.1.17 icmp_seq=1 Destination Host Unreachable
From 192.168.1.17 icmp_seq=2 Destination Host Unreachable
From 192.168.1.17 icmp_seq=3 Destination Host Unreachable
From 192.168.1.17 icmp_seq=4 Destination Host Unreachable

--- mo-ge-0-0-10 ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3015ms pipe 3
root@mo-ge-0-0-2:/root#


Again, that's exactly what I wanted to see! The hosts on ge-0/0/2 on both switches can ping each other, but can't ping hosts on ge-0/0/10. Since both VLANs are working properly across the uplink between the two switches, we know that VLAN 20 (VoIP) is being 802.1q tagged properly on ge-0/0/21, and the default VLAN (PCs and servers) is being carried as the native (untagged) VLAN on the same port.

Since the EX3200 contains routing code as well as switching code, we can configure our routing protocols to route from one VLAN to the other, if we choose:

root@main3200# show protocols ospf
export ospf-default;
area 0.0.0.0 {
    interface ge-0/0/21.0;
    interface vlan.0 {
        passive;
    }
    interface vlan.20 {
        passive;
    }
    interface ge-0/0/19.0 {
        passive;
    }
}

[edit]
root@main3200#


By placing both vlan.0 and vlan.20 into the OSPF process, the router will now route between the two VLAN interfaces (what is called, "Routing-on-a-Stick," or sometimes, a "one-armed router").

JNCIA Lesson 4 -- Routing Policies and Firewall Filters

There's a particularly corny scene in the movie "Firewall" where Harrison Ford's character takes over for a junior network admin when the bank he works for is being DoS'd -- or maybe it was just a brute-force password guessing attack, I can't remember now -- by an outside attacker. Peering intently at the screen, Ford thinks for a minute, then pecks out a sequence of commands on the screen, finishing with a smug, "That should hold them up for a while," to which the junior admin replies, "It would hold me up!" What makes the scene corny is that they catch just a second of the monitor on-camera, and I could see that Ford (or more likely, their technical consultant) had typed a simple Cisco access control list to block traffic from a specific source IP address. Any competent network admin can tell you that a serious attacker could easily repeat the attack from another address, and another, and another, ad infinitum, until the increasingly complex access control list alone causes as much trouble as the initial attack.

However, ACL's -- or Juniper's even more flexible and powerful firewall filters -- have a valid role in network security, and on JunOS, they provide for an even more mundane -- yet essential -- role in configuring dynamic routing. Let me start with a simple example: suppose you have a router at your main office location, with two branch offices connected through a private network provided by your service provider (Metro-Ethernet service, for example). You have multiple VLANs on each router which must be able to communicate with each VLAN on the other routers. The main office router has a single Internet connection to your upstream service provider. You want each of the branch office routers to be able to connect to the Internet through your main office router. When finished, the network should look something like this:



In the last lesson, we configured a simple network using OSPF to route between three LAN networks. This time, however, we have added a fourth route to our ISP. Generally, a small or even medium sized business doesn't share routes with their ISP. The ISP doesn't care about routes to your internal network (that's why RFC-1918 was created in the first place), nor does a typical small office router have enough memory or processing power to store the entire Internet's routing table (especially not if using RIP or OSPF, but that's a whole other topic we won't get into now). In fact, if you only have a single connection to your ISP, this is a perfect use for a static route. Router A, which is the only router connected to the upstream service provider, will have a static, default route. If only there were a way to share that route with routers B and C...

On a Cisco router, this would be a piece of cake: you would simply create the default route, then use the "default-information originate" command to tell OSPF to distribute the default route in your OSPF area. On a Juniper, it is (IMHO) more complicated than it needs to be, but it's not really THAT bad. First, just like a Cisco, we'll create the default route:

root@main3200# top

[edit]
root@main3200# set routing-options static route 0.0.0.0/0 next-hop 100.64.170.65

[edit]
root@main3200#


At this point, you should be able to ping onto the Internet (or to a test network beyond the "ISP" router) from Router A. However, from Router B or Router C, there is still no default route defined:

root@branch2-3200# run show route 172.16.0.1

[edit protocols ospf]
root@branch2-3200#


Next, we have to define a routing policy to redistribute this route into OSPF...:

root@main3200# set policy-options policy-statement ospf-default term 1 from route-filter 0.0.0.0/0 exact accept

[edit]
root@main3200#


...and then export that filter into OSPF:

root@main3200# set protocols ospf export ospf-default

[edit]
root@main3200# commit
commit complete

[edit]
root@main3200#


If you try again from Router C...:

root@branch2-3200# run show route 172.16.0.1

inet.0: 10 destinations, 10 routes (10 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both

0.0.0.0/0          *[OSPF/150] 00:01:16, metric 0, tag 0
                    > to 10.11.12.1 via ge-0/0/21.0

[edit protocols ospf]
root@branch2-3200#


Success!!! However, if you're like I was when I first figured this out, you are probably going, "That's the stupidest, most convoluted thing..."

Yeah, I get it, and I don't entirely disagree. Cisco and pretty much everyone else who makes the network gear that I've played with in the past assume that you *want* to share routes (that's what a router is for, after all, right?), and so their default policy is exactly that: when you enable a dynamic routing protocol, it's going to start advertising all the routes it can find, or at the very least, there will be switches ("default-information originate," "redistribute connected," "redistribute static," etc.) that turn on very broad swathes of networks with a single command. However, in such cases, it can be very easy to share more information than you intended, and in fact, can be rather difficult to filter out some of the networks that you don't want to share. JunOS, on the other hand, takes the exact opposite approach, and only shares routes that you explicitly tell the router that you want to share. From a security standpoint, I'd have to say the Juniper approach might -- just maybe -- be the better choice. And honestly, their filtering language is much more flexible and powerful than Cisco's ACL's, IMHO. So, enough with the sales pitch; let's dissect those commands and try to figure out exactly what they mean.

The first command we used was "set routing-options static route 0.0.0.0/0 next-hop 100.64.170.65" which is essentially telling the router, "if you don't know what route to take to reach a destination address, just send it to our default gateway at 100.64.170.65."

The last command was "set protocols ospf export ospf-default" which was telling the router that we want to export the routes defined in a route filter that we named "ospf-default" into our OSPF routing protocol. Again, pretty simple and straightforward.

The magic all happens in the second command, "set policy-options policy-statement ospf-default term 1 from route-filter 0.0.0.0/0 exact accept." There's a lot happening in this command, so let's dissect it a little further. In the first half, "set policy-options policy-statement ospf-default..." we are telling the router that we are going to create a filter, and that we want to name the filter "ospf-default." Next, we define the filter. A filter in JunOS can be a sequence of match-action statements, which is roughly analogous to "if-then" statements in a programming language. You can chain multiple statements together in JunOS to create complex, compound statements, just like you would in a programming language. We want to match basically any destination address, so the pseudo-code for what we want to accomplish looks more or less like this:

if destination-address matches 0.0.0.0/0 then
  forward the packet through the static route that matches the destination 0.0.0.0/0


Okay, that seems easy enough. What if we want to route anything matching 172.16.10.0/24 to one router, and route anything else to a second router? Let's try it. First, we'll configure a physical interface through which we will forward traffic:

root@main3200# set interfaces ge-0/0/19 unit 0 family ethernet-switching

[edit]
root@main3200# set interfaces ge-0/0/19 unit 0 family inet address 100.64.5.2/26

[edit]
root@main3200# show interfaces ge-0/0/19
unit 0 {
    family inet {
        address 100.64.5.2/26;
    }
}

[edit]
root@main3200# commit
commit complete

[edit]
root@main3200#


I have connected a router to ge-0/0/19 on Router A to simulate another remote network (172.16.10.0/24) and connected a remote host on the outside interface of this router, using the IP address 172.16.10.20. On the outside interface of our "Internet" router, connected to ge-0/0/20, I have connected a host using the IP address 172.16.20.237. Connected to branch1-3200, I have a host using the IP address 192.168.2.32, and connected to branch1-3200, I have a host using the IP address 192.168.3.32. Right now, the two 192.168.x.32 hosts can ping each other, and the 172.16.20.237 host:

root@branch2-host1:~# ip addr | egrep -A3 eth0 | egrep "(eth0|inet) "
    inet 192.168.3.32/24 brd 192.168.3.255 scope global eth0
    inet 172.16.0.58/30 brd 172.16.0.59 scope global eth0.21
root@branch2-host1:~# ping -c1 192.168.2.32
PING 192.168.2.32 (192.168.2.32) 56(84) bytes of data.
64 bytes from 192.168.2.32: icmp_req=1 ttl=62 time=5.16 ms

--- 192.168.2.32 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 5.163/5.163/5.163/0.000 ms
root@branch2-host1:~# ping -c1 172.16.20.237
PING 172.16.20.237 (172.16.20.237) 56(84) bytes of data.
64 bytes from 172.16.20.237: icmp_req=1 ttl=61 time=1.34 ms

--- 172.16.20.237 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.342/1.342/1.342/0.000 ms
root@branch2-host1:~#


...and...:

me@branch1-host1:~$ ip addr | egrep eth0 | egrep "(eth0|inet) "
    inet 192.168.2.32/24 brd 192.168.2.255 scope global eth0
me@branch1-host1:~$ ping -c1 192.168.3.32
PING 192.168.3.32 (192.168.3.32) 56(84) bytes of data.
64 bytes from 192.168.3.32: icmp_req=1 ttl=62 time=2.93 ms

--- 192.168.3.32 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.936/2.936/2.936/0.000 ms
me@branch1-host1:~$ ping -c1 172.16.20.237
PING 172.16.20.237 (172.16.20.237) 56(84) bytes of data.
64 bytes from 172.16.20.237: icmp_req=1 ttl=61 time=1.51 ms

--- 172.16.20.237 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.510/1.510/1.510/0.000 ms
me@branch1-host1:~$


However, as of yet, there is no path to the host at 172.16.10.20:

root@branch2-host1:~# ping -c1 172.16.10.20
PING 172.16.10.20 (172.16.10.20) 56(84) bytes of data.
From 100.64.170.79 icmp_seq=1 Time to live exceeded

--- 172.16.10.20 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

root@branch2-host1:~#


...and...:

me@branch1-host1:~$ ping -c1 172.16.10.20
PING 172.16.10.20 (172.16.10.20) 56(84) bytes of data.
From 100.64.170.79 icmp_seq=1 Time to live exceeded

--- 172.16.10.20 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

me@branch1-host1:~$


This is expected, since we currently have a default route, redistributed through OSPF, from the main office router to both branch office routers. We now need to create a second route on the main office router to match 172.16.10.0/24, and redistribute it through OSPF to the branch office routers:

root@main3200# set routing-options static route 172.16.10.0/24 next-hop 100.64.5.1

[edit]
root@main3200# set policy-options policy-statement ospf-default term 2 from route-filter 172.16.10.0/24 exact accept

[edit]
root@main3200# set protocols ospf export ospf-default

[edit]
root@main3200#


We also need to tell the two branch routers how to reach the next-hop address of 100.64.5.1:

root@main3200# set protocols ospf area 0.0.0.0 interface ge-0/0/19.0 passive

[edit]
root@main3200# commit
commit complete

[edit]
root@main3200#


...and now we have both a default route through the "ISP" through ge-0/0/20 and to the host on 172.16.10.20 through ge-0/0/19, shared with all three office locations.