Now that you've got your new EX3200 switches upgraded to the latest stable release, let's start working with the
Layer-3 features of the switch. We'll start by reviewing a few basic concepts on how Juniper implements routing.
Juniper routers create two categories of databases while deciding how to forward packets from one network to another: the routing table and the forwarding table. The routing table is created by the routing engine, and contains the routes to various networks. The routing engine then copies the forwarding table to the packet forwarding engine, which uses the forwarding table to decide how to forward packets that come into the router.
Notice that I said JunOS creates two
categories of databases. In truth, JunOS supports multiple routing instances, and therefore, multiple routing tables. If you run the "show route" command...:
root@main3200# run show route
inet.0: 14 destinations, 14 routes (14 active, 0 holddown, 0 hidden)
<...snip...>
...notice that it starts with the string, "inet.0." The inet.0 routing table is the default table for IPv4 routes. On some devices, you might also see...:
__juniper_private1__.inet.0
...which is a routing table used within JunOS to communicate with the router itself. There are also several other routing tables created by JunOS for various purposes:
There are two commands which are useful for troubleshooting routing and forwarding problems: "show route forwarding-table" and "show pfe route ip" (you can also use "show pfe route ipv6," "show pfe route mpls," and "show pfe route summary"). Since both of these commands produce a
LOT of output, I won't show examples -- just go play with them :)
For a concise summary of the routes the router knows about, use the "show route" command:
root@main3200> show route
inet.0: 10 destinations, 10 routes (10 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
10.11.12.0/30 *[Direct/0] 22:36:20
> via ge-0/0/21.0
10.11.12.1/32 *[Local/0] 22:36:29
Local via ge-0/0/21.0
100.64.170.79/32 *[Local/0] 22:36:29
Reject
192.168.1.0/24 *[Direct/0] 22:36:20
> via vlan.0
192.168.1.1/32 *[Local/0] 22:36:31
Local via vlan.0
192.168.2.0/24 *[OSPF/10] 22:35:32, metric 2
> to 10.11.12.2 via ge-0/0/21.0
192.168.10.0/24 *[Direct/0] 22:36:20
> via vlan.20
192.168.10.1/32 *[Local/0] 22:36:31
Local via vlan.20
224.0.0.5/32 *[OSPF/10] 22:36:32, metric 1
MultiRecv
224.0.0.22/32 *[IGMP/0] 22:36:32
MultiRecv
root@main3200>
As you can see, this router already has been configured with routes to various networks. Some of these routes are created automatically, because the networks are directly connected to the router...:
10.11.12.0/30 *[Direct/0] 22:36:20
> via ge-0/0/21.0
10.11.12.1/32 *[Local/0] 22:36:29
Local via ge-0/0/21.0
...
192.168.1.0/24 *[Direct/0] 22:36:20
> via vlan.0
192.168.1.1/32 *[Local/0] 22:36:31
Local via vlan.0
...and some of these routes are known through
Dynamic Routing Protocols:
192.168.2.0/24 *[OSPF/10] 22:35:32, metric 2
> to 10.11.12.2 via ge-0/0/21.0
I'll clear out the routing configurations on this router, and we'll start over with a very simple example: routing from this switch to a second EX3200 that we will call "branch3200", which will be connected with an
Ethernet crossover cable:
root@main3200# delete routing-options
[edit]
root@main3200# delete protocols ospf
[edit]
root@main3200# delete policy-options
[edit]
root@main3200# commit
commit complete
[edit]
root@main3200#
For the moment, don't worry too much about the meaning of each of those "delete..." statements. In short, all three statements were necessary to delete all of the routes and routing options that I had created on the switch earlier. By the end of this lesson, the reason for each of those "delete" statements should be clear :)
Back to routing...We will connect ge-0/0/21 on each switch via the crossover cable. Since routing occurs at
Layer-3, we'll need to configure an IP address on each switch. I'll assume for now that you are familiar with the concept of
subnetting a network; if you aren't, spend some quality time with Google before continuing with these lessons, as a lot of what we will be doing will require that you understand the concept. So, operating on that assumption, we'll create a /30 network between these two EX3200's, since we only need two IP addresses between them (one for each EX3200). I'll assign the IP address 10.11.12.1/30 to main3200 and 10.11.12.2/30 to branch3200:
root@main3200# delete interfaces ge-0/0/21 unit 0 family ethernet-switching
[edit]
root@main3200# set interfaces ge-0/0/21 unit 0 family inet address 10.11.12.1/30
[edit]
root@main3200#
...and...:
root@branch3200# delete interfaces ge-0/0/21 unit 0 family ethernet-switching
[edit]
root@branch3200# set interfaces ge-0/0/21 unit 0 family inet address 10.11.12.2/30
[edit]
root@branch3200#
At this point, we should be able to ping between the two switches:
root@main3200# run ping 10.11.12.2
PING 10.11.12.2 (10.11.12.2): 56 data bytes
64 bytes from 10.11.12.2: icmp_seq=0 ttl=64 time=5.879 ms
64 bytes from 10.11.12.2: icmp_seq=1 ttl=64 time=1.767 ms
^C
--- 10.11.12.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.767/3.823/5.879/2.056 ms
[edit]
root@main3200#
Success! Since these two switches are directly connected across a single broadcast domain, we don't have to configure any routing at all to communicate over the 10.11.12.0/30 network. In
Lesson 1 we configured a management IP address of 192.168.1.1/24 on interface vlan.0 on the main3200 switch. Let's assume that we have a mangement IP address of 192.168.2.1/24 on interface vlan.0 on the branch3200 switch. Can we ping from 192.168.1.1 to 192.168.2.1? Let's try it and see:
root@main3200# run ping 192.168.2.1
PING 192.168.2.1 (192.168.2.1): 56 data bytes
ping: sendto: No route to host
ping: sendto: No route to host
^C
--- 192.168.2.1 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
[edit]
root@main3200#
Nope! By default a router (or layer-3 switch, like the EX3200's we are using) only knows directly connected routes. In other words, main3200 only knows how to reach 10.11.12.0/30 and 192.168.1.0/24, and branch3200 only knows how to reach 10.11.12.0/30 and 192.168.2.0/24. Since both switches know how to reach 10.11.12.0/30, they can communicate with each other over this network, but since they don't have the 192.168.x.0/24 networks in common, main3200 can't reach 192.168.2.x, nor can branch3200 reach 192.168.1.x. However, we can fix that very easily:
root@main3200# set routing-options static route 192.168.2.0/24 next-hop 10.11.12.2
[edit]
root@main3200# commit
commit complete
[edit]
root@main3200#
...and on the branch3200:
root@branch3200# set routing-options static route 192.168.1.0/24 next-hop 10.11.12.1
[edit]
root@branch3200# commit
commit complete
[edit]
root@branch3200#
Let's see how a ping from the main3200 switch to the management IP of the branch3200 switch works now:
root@main3200# run ping 192.168.2.1
PING 192.168.2.1 (192.168.2.1): 56 data bytes
64 bytes from 192.168.2.1: icmp_seq=0 ttl=64 time=2.043 ms
64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=1.622 ms
^C
--- 192.168.2.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 1.622/1.833/2.043/0.211 ms
[edit]
root@main3200#
Much better! With that one line of code, we told the main3200 switch that, in order to reach the 192.168.2.0/24 network, we had to talk to the router (we'll use "router" synonymously with layer-3 switch, from here on) at 10.11.12.2, and we told the branch3200 switch to talk to 10.11.12.1 to communicate with 192.168.1.0/24. Even better, the two end-point routers don't have to be directly connected for this to work. You can have an arbitrary number of routers between end-points (sort of -- more on this later) and, as long as each router has a next-hop for the destination network, you can "chain" routes together to reach your destination.
For example, suppose you had three routers, router A, router B and router C. Each router has a 192.168.x.1 management IP, 192.168.1.1 for router A, 192.168.2.1 for router B and 192.168.3.1 for router C. Router A is connected to router B on the 10.11.12.0/30 network, just as we've described with main3200 and branch3200 above. Router B is connected to router C on the 172.16.0.0/30 network. In that case, on router A, you would run the command "set routing-options static route 192.168.3.0/24 next-hop 10.11.12.2", just as we did before. On router B, you would run
TWO commands, "set routing-options static route 192.168.3.0/24 next-hop 172.16.0.2" and "set routing-options static route 192.168.1.0/24 next-hop 10.11.12.1." On router C, you would run a single command again, "set routing-options static route 192.168.1.0/24 next-hop 172.16.0.1." If router A wanted to communicate with the 192.168.2.0/24 network on router B, then on router A you would also need to add "set routing-options static route 192.168.2.0/24 next-hop 10.11.12.2" as well, and if router C wanted to communicate with the 192.168.2.0/24 network on router B, you would have to add the command "set routing-options static route 192.168.2.0/24 next-hop 172.16.0.1" also. Instead of two commands for two routers, we now have eight commands for three routers -- that's an exponential growth (2^n, where n is the number of routers in the network) for full communication across the network. Clearly, if you have a small network, static routes are fine, but for large networks (where "large" doesn't really have to be all that large at all), creating static routes is a very time-consuming and error-prone proposition.
Fortunately, there's a solution for this problem. Very early on, router manufacturers decided that, while there were scenarios where statically routing between networks was appropriate, this was actually the kind of work that a computer -- and an average router is nothing more than a low-powered computer with very specific software and two or more network ports -- is very good at performing. Consequently, they developed dynamic routing protocols: algorithms that share routes between devices automatically, relieving the network administrator of the necessity of statically configuring all of the routes between various network devices.
One of the most common routing protocols in use is OSPF (Open Shortest Path First). Let's delete our static routes and replace them with a simple OSPF configuration:
root@main3200# top
[edit]
root@main3200# edit protocols ospf
[edit protocols ospf]
root@main3200# set area 0.0.0.0 interface ge-0/0/21.0
[edit protocols ospf]
root@main3200# set area 0.0.0.0 interface vlan.0 passive
[edit protocols ospf]
root@main3200# commit
commit complete
[edit protocols ospf]
root@main3200#
Now, let's see if our configuration works:
root@main3200# run show route protocol ospf
inet.0: 10 destinations, 10 routes (10 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
192.168.2.0/24 *[OSPF/10] 00:02:14, metric 2
> to 10.11.12.2 via ge-0/0/21.0
224.0.0.5/32 *[OSPF/10] 00:03:35, metric 1
MultiRecv
[edit protocols ospf]
root@main3200#
Perfect! We have a route to 192.168.2.0/24 on main3200.
One other tool that is useful for debugging OSPF routing problems is the "show ospf neighbor" command. Here is the output from immediately after committing the OSPF configuration. In particular, watch how the "State" changes as the two EX3200's begin to build the OSPF communications:
root@main3200# run show ospf neighbor
Address Interface State ID Pri Dead
10.11.12.2 ge-0/0/21.0 2Way 10.11.12.2 128 39
[edit protocols ospf]
root@main3200# run show ospf neighbor
Address Interface State ID Pri Dead
10.11.12.2 ge-0/0/21.0 ExStart 10.11.12.2 128 33
[edit protocols ospf]
root@main3200# run show ospf neighbor
Address Interface State ID Pri Dead
10.11.12.2 ge-0/0/21.0 Full 10.11.12.2 128 36
[edit protocols ospf]
root@main3200#
In this sequence of captures, you can see the OSPF process begin establishing the OSPF adjacency with the neighbor router ("2Way"), exchanging routes with the neighbor ("ExStart") and fully converged ("Full"). If the routers don't move to the "Full" state after a couple of minutes, then something is wrong and you should make sure 1) that your configs are good, and 2) that you can ping from one router to the other. Once the state has changed to "Full", you can run the "show route protocol ospf" command to verify that all of the routes are being shared properly.
Let's discuss a couple of the statements in our OSPF configuration in a little more detail:
root@main3200# show
area 0.0.0.0 {
interface ge-0/0/21.0;
interface vlan.0 {
passive;
}
}
[edit protocols ospf]
root@main3200#
First, notice that all of our configuration statements fall under the "area 0.0.0.0" stanza. In OSPF, you can define multiple areas for OSPF to run in, although you always need an area 0.0.0.0 (sometimes shortened to "area 0" on some vendors' equipment, although Juniper will rewrite "area 0" as "area 0.0.0.0"). To understand areas, keep in mind that OSPF advertises routes within an area, so once a network becomes large, you can improve performance and reduce network overhead by segmenting your network into smaller subnetworks to reduce the number and size of advertisements. Area 0.0.0.0 is of particular importance because it is the "
backbone network", that is, the portion of the network that connects all of the other areas (if any) together. In our case, the network is very small (just two switches), so we have put all of the networks in area 0.0.0.0.
Second, notice that under area 0.0.0.0, we have listed two interfaces, ge-0/0/21.0 and vlan.0. When we listed these interfaces, we told OSPF that we want to enable OSPF routing on these interfaces. For vlan.0, we further modified this statement by appending the "passive" parameter, which tells OSPF that, even though we want to make this interface part of the OSPF area, we don't want to form OSPF adjacencies through this interface.
That leaves us with one question remaining for this section: suppose we had multiple routes to a particular network, say one route that was defined statically, and another route to the same network that was defined through a dynamic routing protocol such as OSPF. Which patch would the router take to reach the destination? JunOS has predicted that such a scenario might occur, and has already addressed the issue through
route preferences.
Basically, route preferences set a ranking of routes depending upon the way the route was derived. For example, directly connected routes are most preferable, statically defined routes are slightly less preferable, OSPF routes are even less preferable, RIP is less preferable than OSPF and BGP is the least preferable route of all (
reference). These preferences aren't just academic, mind you. I once had to troubleshoot a routing problem with my upstream provider where I was experiencing a routing loop trying to reach a remote location from a second remote location in my network. My upstream provider spent several days claiming that he was advertising the proper routes through his core, until I finally asked him to check the static routing at one of the remote office locations. Since static routes are more preferable than dynamic routes, the old, incorrect static route was overriding the route he was advertising dynamically through his core, and was routing traffic to this one subnet back to my edge router, causing a loop.
This has only scratched the surface of routing on Juniper devices, but we'll save the more advanced topics for the next lesson.