2
0
mirror of https://github.com/knorrie/network-examples synced 2025-08-29 13:39:01 +00:00

OSPF intro: Whee

This commit is contained in:
Hans van Kranenburg 2015-06-07 02:46:13 +02:00
parent 381746eb45
commit 2622e52481
3 changed files with 284 additions and 13 deletions

View File

@ -47,7 +47,7 @@ To discover the full topology of the network, the following happens:
* Receive the same information from neighbour routers. * Receive the same information from neighbour routers.
* When an information card of a router arrives, store it, and send it out again on all other interfaces that are not a stub, unless the information of this particular router was already received before. * When an information card of a router arrives, store it, and send it out again on all other interfaces that are not a stub, unless the information of this particular router was already received before.
And magically... After a short burst of network traffic, all routers have now received each other's information, and are in possesion of the four cards with information. Now that each router has all information about the other ones, let's see what happens when we simply connect them together, turning the shared subnet ranges into a subnet between the routers: And magically... After a short burst of network traffic, all routers have now received each other's information, and are in possesion of the four cards with information. Now that each router has all information about the other ones, let's see what happens when we simply connect the information about the four different routers together, turning the shared subnet ranges into a subnet between the routers:
![OSPF network, joined together](/ospf-intro/ospf-together.png) ![OSPF network, joined together](/ospf-intro/ospf-together.png)
@ -76,21 +76,292 @@ Ok, first of all, to be honest, the stub links still look a bit sad, so let's co
![OSPF network, joined together with some hosts](/ospf-intro/ospf-together-hosts.png) ![OSPF network, joined together with some hosts](/ospf-intro/ospf-together-hosts.png)
### Building the containers ## Building the containers
Let's build some containers! Let's build some containers! If you don't have [a lab environment](/lxcbird/README.md) with a template 'birdbase' container yet, create it!
* -> clone containers To create the eight containers we need, connected together in different networks, the following steps are needed:
* -> setup interfaces
* -> copy config
* -> start all containers
* -> verify in containers that you can `ip r` and only see connected networks
To be able to use the OSPF routing protocol, we need to run a program on each router that implements it. BIRD, the BIRD Internet Routing Daemon is one of those and I'll be using it for all examples and tutorials here. Blah container cloned from birdbase already has bird blah. 1. Clone this git repository somewhere to be able to use some files from the ospf-intro/lxc/ directory inside.
Since the network interfaces and IP addresses of connected subnets are already defined in the operating system configuration, we only need to provide the following extra information to be able to start using the OSPF routing protocol: 2. lxc-clone the birdbase container several times:
* A 32 bit number, the Router ID, which is a unique identifier of this router. We'll use the 10.9.99.X address of each router for that. lxc-clone -s birdbase R1
* A list of interfaces which should participate in the OSPF network, and whether the interfaces are or are not a stub interface. lxc-clone -s birdbase R2
lxc-clone -s birdbase R5
lxc-clone -s birdbase R6
lxc-clone -s birdbase H12
lxc-clone -s birdbase H10
lxc-clone -s birdbase H8
lxc-clone -s birdbase H5
Blah default config file, add OSPF config, `ip r`, `ip a`, interfaces, blah blah etc... 3. Set up the network interfaces in the lxc configuration. This can be done by removing all network related configuration that remains from the cloned birdbase container, and then appending all needed interface configuration by running the fixnetwork.sh script that can be found in `ospf-intro/lxc/` in this git repository. Of course, have a look at the contents of the script first, before executing it.
sed -i '/lxc.network/d' R*/config H*/config
. ./fixnetwork.sh
Since this example is only using IPv4 and single IP addresses on the interfaces, I simply added them to the lxc configuration instead of the network/interfaces file inside the container.
4. Copy extra configuration into the containers. The ospf-intro/lxc/ directory inside this git repository contains a little file hierarchy that can just be copied over the configuration of the containers. For each router, it's a network/interfaces configuration file which adds an IP address that corresponds with the Router ID to the loopback interface, and a simple BIRD configuration file that serves as a starting point for our next steps.
5. Start all containers
lxc-start -d -n R1
lxc-start -d -n R2
lxc-start -d -n R5
lxc-start -d -n R6
lxc-start -d -n H12
lxc-start -d -n H10
lxc-start -d -n H8
lxc-start -d -n H5
6. Verify connectivity and look around a bit. Here's an example for R1:
lxc-attach -n R1
root@R1:/#
root@R1:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 10.9.99.1/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
247: vlan1001: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:00:0a:00:01:05 brd ff:ff:ff:ff:ff:ff
inet 10.0.1.5/24 brd 10.0.1.255 scope global vlan1001
valid_lft forever preferred_lft forever
inet6 fe80::aff:fe00:105/64 scope link
valid_lft forever preferred_lft forever
249: vlan1012: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:00:0a:01:02:07 brd ff:ff:ff:ff:ff:ff
inet 10.1.2.7/24 brd 10.1.2.255 scope global vlan1012
valid_lft forever preferred_lft forever
inet6 fe80::aff:fe01:207/64 scope link
valid_lft forever preferred_lft forever
251: vlan1356: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 02:00:0a:03:38:01 brd ff:ff:ff:ff:ff:ff
inet 10.3.56.1/24 brd 10.3.56.255 scope global vlan1356
valid_lft forever preferred_lft forever
inet6 fe80::aff:fe03:3801/64 scope link
valid_lft forever preferred_lft forever
root@R1:/# ip r
10.0.1.0/24 dev vlan1001 proto kernel scope link src 10.0.1.5
10.1.2.0/24 dev vlan1012 proto kernel scope link src 10.1.2.7
10.3.56.0/24 dev vlan1356 proto kernel scope link src 10.3.56.1
root@R1:/# ping -c 3 10.3.56.8
PING 10.3.56.8 (10.3.56.8) 56(84) bytes of data.
64 bytes from 10.3.56.8: icmp_seq=1 ttl=64 time=0.545 ms
64 bytes from 10.3.56.8: icmp_seq=2 ttl=64 time=0.084 ms
64 bytes from 10.3.56.8: icmp_seq=3 ttl=64 time=0.078 ms
--- 10.3.56.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.078/0.235/0.545/0.219 ms
root@R1:/#
root@R1:/# traceroute 10.34.2.5
traceroute to 10.34.2.5 (10.34.2.5), 30 hops max, 60 byte packets
connect: Network is unreachable
Looking good! :-) Feel free to test some more and by attaching to the console of containers and playing around.
## Basic BIRD configuration
To be able to use the OSPF routing protocol, we need to run a program on each router that implements it. BIRD, the BIRD Internet Routing Daemon is one of those and I'll be using it for all examples and tutorials here.
Let's have a look at the BIRD configuration of R6:
# cat R6/rootfs/etc/bird/bird.conf
router id 10.9.99.6;
protocol kernel {
import none;
export all;
}
protocol device {
# defaults...
}
This is a really basic BIRD configuration:
* The Router ID is set to a unique value in the network, which is 10.9.99.6 for this router. Actually, this is not an IP address. It's just a 32 bit value, but it's written in the same notation we use for IPv4 address, instead of 0x0a096306 or 168387334.
* A kernel protocol. This is not a real routing protocol, but it's the way BIRD uses to export route information from the internal BIRD routing table to the Linux kernel (remember, the control plane programs the forwarding plane). The filters are set to export all routes that BIRD will be learning from other routers to the Linux kernel routing table, which is fine for now.
* A device protocol. This is also not a real routing protocol, but the way BIRD uses to import information about the local network interfaces that are already present in this routers. Usually this is added to your BIRD configuration and just sits there, doing its thing.
As you have seen above, all of the routers currently only see their connected subnets. R1 which was used as an example above has no idea how to reach a computer with IP address 10.34.2.5, because it has no available route to a network this address is in:
root@R6:/# ip r
10.0.1.0/24 dev vlan1001 proto kernel scope link src 10.0.1.8
10.34.2.0/24 dev vlan1034 proto kernel scope link src 10.34.2.1
`ip r` shows the Linux kernel route table, which is used to actually forward packets. The BIRD process has its own internal routing table, which can also be shown:
root@R6:/# birdc show route
BIRD 1.4.5 ready.
root@R6:/#
Well, actually it's still empty now. :-)
birdc is a little program which connects to a running BIRD process for diagnostics and like manupulation of the running protocols, like disabling or enabling them:
root@R6:/# birdc
BIRD 1.4.5 ready.
bird> show route
bird> show ?
show bfd ... Show information about BFD protocol
show interfaces Show network interfaces
show memory Show memory usage
show ospf ... Show information about OSPF protocol
show protocols [<protocol> | "<pattern>"] Show routing protocols
show roa ... Show ROA table
show route ... Show routing table
show static [<name>] Show details of static protocol
show status Show router status
show symbols ... Show all known symbolic names
bird> show status
BIRD 1.4.5
Router ID is 10.9.99.6
Current server time is 2015-06-07 00:51:52
Last reboot on 2015-06-07 00:02:37
Last reconfiguration on 2015-06-07 00:43:57
Daemon is up and running
bird>
bird> show protocols
name proto table state since info
kernel1 Kernel master up 00:02:37
device1 Device master up 00:02:37
## Configuring OSPF
The moment we've all been waiting for! Add the following to bird.conf of R6. Editing the bird.conf file can be done from outside the container.
protocol ospf {
area 0 {
interface "lo" {
stub;
};
interface "vlan1001" {
};
interface "vlan1034" {
stub;
};
};
}
Now, tell BIRD to reload the configuration:
root@R6:/# birdc
BIRD 1.4.5 ready.
bird> configure
Reading configuration from /etc/bird/bird.conf
Reconfigured
An OSPF protocol instance has been started now, which has been provided with information that closely relates to the little "router information cards" seen earlier:
![OSPF R6](/ospf-intro/ospf-r6.png)
The interface in network `10.0.1.0/24` has been configured as active OSPF interface. The interface in `10.34.2.0/24` is a stub, and also the Linux loopback interface has been specified as stub, causing the `10.9.99.6/32` address that is present on the loopback interface to be included in the OSPF process.
After starting OSPF, the Linux kernel routing table still looks unchanged, but the routing table inside BIRD has changed:
root@R6:/# ip r
10.0.1.0/24 dev vlan1001 proto kernel scope link src 10.0.1.8
10.34.2.0/24 dev vlan1034 proto kernel scope link src 10.34.2.1
root@R6:/# birdc show route
BIRD 1.4.5 ready.
10.0.1.0/24 dev vlan1001 [ospf1 00:58:01] * I (150/10) [10.9.99.6]
10.9.99.6/32 dev lo [ospf1 00:58:01] * I (150/0) [10.9.99.6]
10.34.2.0/24 dev vlan1034 [ospf1 00:58:01] * I (150/10) [10.9.99.6]
Since BIRD has been told which interfaces are participating in the OSPF protocol, it has been able to determine which network ranges are active on those interfaces. When talking to other OSPF routers, this is the information that will be sent to them in the R6 information message!
There are more useful commands to show what R6 is currently seeing in the OSPF network:
bird> show ospf topology
area 0.0.0.0
router 10.9.99.6
distance 0
bird> show ospf neighbors
ospf1:
Router ID Pri State DTime Interface Router IP
Only, the output is not very exciting, because apparently there are no other routers available yet which can answer the Hellos that R6 is sending onto vlan1001...
## A second OSPF router, or more!
The inevitable must happen. Right now, you should know enough to be able to configure OSPF on R1 as well, which has two active OSPF interfaces, the stub interface which connects to the network with H8, and of course the loopback interface.
Go ahead, do it, now!
After adding the configuration and making BIRD reload it, `birdc show protocols` should show an active OSPF protocol. Now, just wait for a few seconds and do `ip r` again on R6:
root@R6:/# ip r
10.0.1.0/24 dev vlan1001 proto kernel scope link src 10.0.1.8
10.1.2.0/24 via 10.0.1.5 dev vlan1001 proto bird
10.3.56.0/24 via 10.0.1.5 dev vlan1001 proto bird
10.9.99.1 via 10.0.1.5 dev vlan1001 proto bird
10.34.2.0/24 dev vlan1034 proto kernel scope link src 10.34.2.1
I guess it's not very useful any more to continue typing much more text in this tutorial page now, because I'm quite surely losing your attention. :-D Just go ahead, and configure OSPF on the other two routers and see what happens. One fun thing to do is to start a `watch ip r` on R6 and see live changes of what will happen while you're working on the other routers.
When enabling OSPF on all four routers, you should be able to reach anything from anything in the whole network.
root@H12:/# traceroute -n 10.34.2.5
traceroute to 10.34.2.5 (10.34.2.5), 30 hops max, 60 byte packets
1 10.50.1.1 0.199 ms 0.227 ms 0.119 ms
2 10.1.2.56 0.238 ms 0.234 ms 0.284 ms
3 10.0.1.8 0.283 ms 0.282 ms 0.332 ms
4 10.34.2.5 0.310 ms 0.389 ms 0.246 ms
Or...
root@H12:/# mtr -n -c 3 -r 10.3.56.8
Start: Sun Jun 7 01:46:49 2015
HOST: H12 Loss% Snt Last Avg Best Wrst StDev
1.|-- 10.50.1.1 0.0% 3 0.1 0.2 0.1 0.3 0.0
2.|-- 10.1.2.7 0.0% 3 0.1 0.2 0.1 0.3 0.0
3.|-- 10.3.56.8 0.0% 3 0.1 0.2 0.1 0.4 0.0
## More Dynamics!
There's two more topics I want to cover before ending this tutorial. The first one is how the network will handle changes in the availability of paths.
Attach to H12 and start an `mtr -n 10.34.2.5`. In my case here, it shows a path via `10.50.1.1` (R2), `10.1.2.56` (R5) and `10.0.1.8` (R6). Now, just for fun, do an `ip link set down vlan1012` on R5 if your traceroute shows the same path, or if the route is over R1, just down an interface on R2 instead, and look what's happening to your running mtr output. Doing this is equivalent to pulling a network cable out of a network port of a "real" router.
Here's mine:
My traceroute [v0.85]
H12 (0.0.0.0) Sun Jun 7 01:56:35 2015
Keys: Help Display mode Restart statistics Order of fields quit
Packets Pings
Host Loss% Snt Last Avg Best Wrst StDev
1. 10.50.1.1 0.0% 230 0.1 0.1 0.1 0.4 0.0
2. 10.1.2.56 0.9% 230 0.1 0.1 0.1 0.3 0.0
10.1.2.7
3. 10.0.1.8 0.9% 230 0.1 0.1 0.1 0.4 0.0
4. 10.34.2.5 0.9% 230 0.1 0.1 0.1 0.4 0.0
When I disabled the interface on R5, BIRD on R5 got notified by netlink that the interface went down. OSPF on R5 had to change its information card immediately and send it out again. But... it was only able to send it out on the 10.0.1.0/24 network. So it did, and R1 and R6 received it. Since R1 had not seen an update on the lower side of the network, it notified routers in there of the change and R2 was able to recalculate the shortest paths to the entire network after changing its view of the complete network topology with the missing link between R5 and the 10.1.2.0/24 network. After doing so, R2 determined that the current open shortest path to 10.34.2.5 had to be via 10.1.2.7 and used the BIRD kernel protocol to retract the route to 10.34.2.0/24 via 10.1.2.56 and inserted a new route into the Linux kernel routing table which points to 10.1.2.7 as next hop for 10.34.2.0/24. And then, mtr noticed there was a change in the path.
Apparently, I lost a ping while the network was busy to get into a stable converged state again. ;-(
## Next...
There are numerous pages with information about OSPF on the internet. Since I could not really find one of them that did not directly deep-dive into 100s of pages of concepts like different type of LSAs, DR, BDR, Areas, and a lot of other complex things instead of just showing that a bunch of routers can talk to each other, I created this tutorial to prove routing protocols are fun, and to encourage you to have fun building networks. :-)
First of all, don't forget to take a look at the BIRD documentation about OSPF. You can find it at User's guide -> Protocols -> OSPF at the [BIRD web page](http://bird.network.cz/). There's a lot more options than "stub". :) While I just proved you don't need to know about them to set up an interesting network with dynamic routing, there must be scenarios in which they can be very useful. For example:
* If there are untrusted hosts inside your routing vlans, you might want to use password authentication.
* If you want to decrease the time until the network gets reconfigured when a router crashes without notifying anyone, you might want to play with hello timers, or even bfd.
* Equal cost multipath routing (ECMP) is a big thing nowadays, which is used a lot to load balance traffic over multiple paths to a destination instead of choosing only one as best path. You can even enable that in the network we just built by just specifying `ecmp yes` in the OSPF configuration and see what effect it has on the output of `ip r` on the linux command line. Just search for information on it on the Internet to learn more.
* 'Cost' is an aspect that is fundamental to OSPF and the calculation of the shortest paths in the network. Traditionally, cost is related to the bandwith of a link between routers, and causes higher bandwith connections to be prefered above lower bandwith connections. Since we're working with switched Gigabit/s networks by default now, if it's not 10Gb/s, in the datacenter and even in our office, I've just been ignoring that.
Well, after completing this tutorial, I also encourage you to start reading the other "An Introduction to OSPF" like pages on the internet, since they should be a lot easier to understand while having seen it work for real! :D

BIN
ospf-intro/ospf-r6.dia Normal file

Binary file not shown.

BIN
ospf-intro/ospf-r6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB