mirror of
https://github.com/knorrie/network-examples
synced 2025-08-22 18:19:12 +00:00
BGP Intro: Configure BGP between R3 and R10!
This commit is contained in:
parent
a409ba3618
commit
7a267280db
@ -15,9 +15,9 @@ Let's look at the same picture again, hiding less information:
|
||||
|
||||
The picture shows two networks, which are interconnected through router `R3` and `R10`.
|
||||
|
||||
* A complete network under control of somebody has an AS ([Autonomous System](https://tools.ietf.org/html/rfc1930)) number. By specifying the AS number when configuring BGP connections, we let it know if the neighbour is in our own network (our AS), or in an external network (another AS).
|
||||
* If neighbouring routers between different networks are directly connected, they often interconnect using a minimal sized network range. For IPv4, this is usually a `/30` and for IPv6 a `/120` or a `/126` prefix, containing only the two routers. In the example above, the small network ranges are taken from the network of `AS64080`.
|
||||
* A complete network under control of somebody has an AS ([Autonomous System](https://tools.ietf.org/html/rfc1930)) number. This number will be used later in the BIRD BGP configuration.
|
||||
* The routes that are published to another network are as aggregated as possible, to minimize the amount of them. While the internal routing table in for example `AS64080` might contain dozens of prefixes, for each little vlan, and probably a number of single host routes (IPv4 `/32` and IPv6 `/128`), they're advertised to the outside as just three routes in total.
|
||||
* If neighbouring routers between different networks are directly connected, they often interconnect using a minimal sized network range. For IPv4, this is usually a `/30` and for IPv6 a `/120` or a `/126` prefix, containing only the two routers. In the example above, the small network ranges are taken from the network of `AS64080`.
|
||||
|
||||
## OSPF vs. BGP
|
||||
|
||||
@ -35,14 +35,12 @@ BGP:
|
||||
|
||||
So, OSPF is an IGP (Interior Gateway Protocol) and BGP is an EGP (Exterior Gateway Protocol). BGP can connect OSPF networks to each other, hiding a lot of detail inside them.
|
||||
|
||||
## BGP and OSPF with BIRD
|
||||
## BGP and OSPF with BIRD: Setting up the containers and networks
|
||||
|
||||
In the second half of this tutorial we'll configure a network, using OSPF, BGP and the BIRD routing software. BGP wise, it's kept simple, using just a single connection between two networks.
|
||||
|
||||

|
||||
|
||||
### Setting up the containers and networks
|
||||
|
||||
It's starting to look serious now! Thankfully, most of the configuration is provided already, so we can quickly set up this whole network using our LXC environment. Just like in the previous tutorial, the birdbase container can be cloned, after which the lxc network information and configuration inside the containers can be copied into them.
|
||||
|
||||
1. Clone this git repository somewhere to be able to use some files from the bgp-intro/lxc/ directory inside.
|
||||
@ -59,7 +57,7 @@ It's starting to look serious now! Thankfully, most of the configuration is prov
|
||||
lxc-clone -s birdbase H19
|
||||
lxc-clone -s birdbase H34
|
||||
|
||||
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. 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.
|
||||
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 `bgp-intro/lxc/` in this git repository. Of course, have a look at the contents of the script first, before executing it. 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.
|
||||
|
||||
. ./fixnetwork.sh
|
||||
|
||||
@ -150,21 +148,185 @@ It's starting to look serious now! Thankfully, most of the configuration is prov
|
||||
|
||||
As you can see, OSPF is running for IPv4 and IPv6, and has discovered the complete internal network of AS64080.
|
||||
|
||||
Now make sure you can do the following, or answer the following questions:
|
||||
Now make sure you can do the following, and answer the following questions:
|
||||
* From H6, `traceroute -n` and `traceroute6 -n` to a few destinations in AS64080 to get acquainted with the network topology.
|
||||
* Look at the BIRD logging. A fun way to follow the logging is to do `tail -F R*/rootfs/var/log/bird/*.log` from outside the containers, and then start all of them.
|
||||
* Find out why `10.40.217.18` or `2001:db8:40:d910::2` on `R10` cannot be pinged from `R1`, while the route to `10.40.217.16/30` and `2001:db8:40:d910::/120` are actually present in the routing table of `R1` and `R3`.
|
||||
|
||||
## BIRD BGP configuration
|
||||
|
||||
Let's zoom in a bit first, and focus on the connection between `R3` and `R10`. This section will show how to configure the actual BGP connection between those two routers, so they will learn about each others network.
|
||||
|
||||

|
||||
|
||||
The routing table of `R3` contains information about the internal network of its own network, `AS64080`. As you can see, routes to the ranges in `AS65033` are missing.
|
||||
|
||||
root@R3:/# ip r
|
||||
10.40.2.0/24 via 10.40.216.2 dev vlan216 proto bird
|
||||
10.40.3.0/24 via 10.40.216.3 dev vlan216 proto bird
|
||||
10.40.216.0/28 dev vlan216 proto kernel scope link src 10.40.216.1
|
||||
10.40.217.0 via 10.40.216.2 dev vlan216 proto bird
|
||||
10.40.217.1 via 10.40.216.3 dev vlan216 proto bird
|
||||
10.40.217.16/30 dev vlan217 proto kernel scope link src 10.40.217.17
|
||||
|
||||
root@R3:/# ip -6 r
|
||||
2001:db8:40:: via fe80::aff:fe28:d802 dev vlan216 proto bird metric 1024
|
||||
2001:db8:40::1 via fe80::aff:fe28:d803 dev vlan216 proto bird metric 1024
|
||||
unreachable 2001:db8:40::3 dev lo proto kernel metric 256 error -101
|
||||
2001:db8:40:2::/120 via fe80::aff:fe28:d802 dev vlan216 proto bird metric 1024
|
||||
2001:db8:40:3::/120 via fe80::aff:fe28:d803 dev vlan216 proto bird metric 1024
|
||||
2001:db8:40:d8::/120 dev vlan216 proto kernel metric 256
|
||||
2001:db8:40:d910::/120 dev vlan217 proto kernel metric 256
|
||||
fe80::/64 dev vlan216 proto kernel metric 256
|
||||
fe80::/64 dev vlan217 proto kernel metric 256
|
||||
|
||||
Now, add the following configuration to `bird.conf` of `R3`:
|
||||
|
||||
##############################################################################
|
||||
# eBGP R10
|
||||
#
|
||||
|
||||
table t_r10;
|
||||
|
||||
protocol static originate_to_r10 {
|
||||
table t_r10;
|
||||
import all; # originate here
|
||||
route 10.40.0.0/22 blackhole;
|
||||
route 10.40.216.0/21 blackhole;
|
||||
}
|
||||
|
||||
protocol bgp ebgp_r10 {
|
||||
table t_r10;
|
||||
local 10.40.217.17 as 64080;
|
||||
neighbor 10.40.217.18 as 65033;
|
||||
import filter {
|
||||
if net ~ [ 10.0.0.0/8{19,24} ] then accept;
|
||||
reject;
|
||||
};
|
||||
import keep filtered on;
|
||||
export where source = RTS_STATIC;
|
||||
}
|
||||
|
||||
protocol pipe p_master_to_r10 {
|
||||
table master;
|
||||
peer table t_r10;
|
||||
import where source = RTS_BGP;
|
||||
export none;
|
||||
}
|
||||
|
||||
Let me explain a bit about what's going on here. So far, we've used the BIRD protocol types `kernel`, `device` and `ospf`. This configuration snippet introduces three other ones: `static`, `bgp` and `pipe`. Besides that, there's also a table definition on top.
|
||||
|
||||
* By issuing `table t_r10`, we tell BIRD that we'd like to use an extra internal routing table with the name `t_r10`. By default, BIRD always has a routing table named `master`, and now we added a second one. Routing tables in BIRD are just a collection of routes, having some attributes.
|
||||
* The static protocol is used to generate a collection of static routes. In this case, we define a protocol static with name `originate_to_r10`, and connect it to table `t_r10`. The import statement causes the routes that are generated by this static route protocol to be imported into the `t_r10` table. Static routes usually have a target of a neighbor router, using a via statement, but in this case, we don't care about a next hop, since it's just a collection of some prefixes that will be exported via BGP. The blackhole won't be actually used for anything here.
|
||||
* The bgp protocol is named after the router which it's talking to, `R10`, and is also connected to the `t_r10` routing table inside BIRD. It has a local and remote IP address and AS number. The import rules are a bit more complex than a simple `import all`, which also would have been sufficient here. I'll explain more about that later, although I doubt you wouldn't already understand what they do. The export rule contains a simple filter that tells BIRD to push all routes from table `t_r10` that originate from a static protocol to the outside, to `R10`.
|
||||
* The pipe protocol is a simple protocol that is able to move around routes between internal BIRD routing tables. In this case, the pipe protocol `p_master_to_r10` is connected to the central `master` routing table and is looking at table `t_r10`. From table `t_r10`, all routes that originate from an external BGP peer are imported into the master table. Doing so will make sure that the routes that will be learned from the remote network end up in the routing table of the Linux kernel (via the kernel protocol that exports them from the BIRD master table to the outside, to the Linux kernel), while the routes that only were meant to be used to export to the BGP peer (generated by the static protocol) stay in `t_r10`.
|
||||
|
||||
Remember, the internal BIRD routing tables are not used to actually do packet forwarding. During the OSPF tutorial, we already discussed this difference between the "Control Plane" and "Forwarding Plane". Actually, the routing table inside the control plane is usually called the "RIB" (Routing Information Base), while the routing table that is used in the forwarding plane is called the "FIB" (Forwarding Information Base). Just look up all those terms on the internet to see what everyone is saying about them.
|
||||
|
||||
After adding the configuration, fire up the interactive BIRD console, using `birdc`:
|
||||
|
||||
root@R3:/# birdc
|
||||
BIRD 1.4.5 ready.
|
||||
|
||||
bird> show protocols
|
||||
name proto table state since info
|
||||
kernel1 Kernel master up 2015-06-14
|
||||
device1 Device master up 2015-06-14
|
||||
ospf1 OSPF master up 2015-06-14 Running
|
||||
originate_to_r10 Static t_r10 up 23:54:16
|
||||
p_master_to_r10 Pipe master up 23:54:16 => t_r10
|
||||
ebgp_r10 BGP t_r10 start 00:34:16 Active Socket: Connection refused
|
||||
|
||||
bird> show route table t_r10
|
||||
10.40.216.0/21 blackhole [originate_to_r10 23:54:16] * (200)
|
||||
10.40.0.0/22 blackhole [originate_to_r10 23:54:16] * (200)
|
||||
|
||||
Well, the routes are waiting to be pushed to `R10` in the `t_r10` table, and no routes from `AS65033` are visible yet. There's only an ugly "Connection refused"... reminding you that the other end of the BGP connection needs to be configured. Now it's up to you to configure `R10` with the opposite part of the configuration, and make it talk to `R3`!
|
||||
|
||||
When successful, the output of the commands above should show, on `R10`:
|
||||
|
||||
bird> show protocols
|
||||
name proto table state since info
|
||||
kernel1 Kernel master up 2015-06-14
|
||||
device1 Device master up 2015-06-14
|
||||
ospf1 OSPF master up 2015-06-14 Running
|
||||
originate_to_r3 Static t_r3 up 00:48:27
|
||||
ebgp_r3 BGP t_r3 up 00:48:32 Established
|
||||
p_master_to_r3 Pipe master up 00:48:27 => t_r3
|
||||
|
||||
bird> show route table t_r3
|
||||
10.40.216.0/21 via 10.40.217.17 on vlan217 [ebgp_r3 00:48:32] * (100) [AS64080i]
|
||||
10.40.32.0/19 blackhole [originate_to_r3 00:48:27] * (200)
|
||||
10.40.0.0/22 via 10.40.217.17 on vlan217 [ebgp_r3 00:48:32] * (100) [AS64080i]
|
||||
|
||||
bird> show route
|
||||
10.40.217.16/30 dev vlan217 [ospf1 2015-06-14] * I (150/10) [10.40.32.10]
|
||||
10.40.216.0/21 via 10.40.217.17 on vlan217 [ebgp_r3 00:48:32] * (100) [AS64080i]
|
||||
10.40.33.0/26 dev vlan33 [ospf1 2015-06-14] * I (150/10) [10.40.32.12]
|
||||
10.40.36.0/24 via 10.40.33.3 on vlan33 [ospf1 2015-06-14] * I (150/20) [10.40.32.12]
|
||||
10.40.48.0/21 via 10.40.33.2 on vlan33 [ospf1 2015-06-14] * I (150/20) [10.40.32.11]
|
||||
10.40.32.10/32 dev lo [ospf1 2015-06-14] * I (150/0) [10.40.32.10]
|
||||
10.40.32.11/32 via 10.40.33.2 on vlan33 [ospf1 2015-06-14] * I (150/10) [10.40.32.11]
|
||||
10.40.0.0/22 via 10.40.217.17 on vlan217 [ebgp_r3 00:48:32] * (100) [AS64080i]
|
||||
10.40.32.12/32 via 10.40.33.3 on vlan33 [ospf1 2015-06-14] * I (150/10) [10.40.32.12]
|
||||
|
||||
bird> show route export kernel1
|
||||
10.40.216.0/21 via 10.40.217.17 on vlan217 [ebgp_r3 00:48:32] * (100) [AS64080i]
|
||||
10.40.36.0/24 via 10.40.33.3 on vlan33 [ospf1 2015-06-14] * I (150/20) [10.40.32.12]
|
||||
10.40.48.0/21 via 10.40.33.2 on vlan33 [ospf1 2015-06-14] * I (150/20) [10.40.32.11]
|
||||
10.40.32.11/32 via 10.40.33.2 on vlan33 [ospf1 2015-06-14] * I (150/10) [10.40.32.11]
|
||||
10.40.0.0/22 via 10.40.217.17 on vlan217 [ebgp_r3 00:48:32] * (100) [AS64080i]
|
||||
10.40.32.12/32 via 10.40.33.3 on vlan33 [ospf1 2015-06-14] * I (150/10) [10.40.32.12]
|
||||
|
||||
Since there is no explicit name given for the kernel protocol in the configuration, BIRD just names it `kernel1`. As you can see, the table `t_r3` contains the static routes which are exported via BGP to `R3`, and it also contains two routes that were learned from `R3`. Yay! The default `show route` command shows routes that are in the BIRD master table. You can see that the `p_master_to_r3` pipe protocol correctly copied the routes that were learned from `R3` from table `t_r3` to the `master` table. The kernel protocol then exports all dynamically learned routes to the actual forwarding table in the Linux kernel, where they show up as output of `ip route`, labeled with proto bird:
|
||||
|
||||
root@R10:/# ip r
|
||||
10.40.0.0/22 via 10.40.217.17 dev vlan217 proto bird
|
||||
10.40.32.11 via 10.40.33.2 dev vlan33 proto bird
|
||||
10.40.32.12 via 10.40.33.3 dev vlan33 proto bird
|
||||
10.40.33.0/26 dev vlan33 proto kernel scope link src 10.40.33.1
|
||||
10.40.36.0/24 via 10.40.33.3 dev vlan33 proto bird
|
||||
10.40.48.0/21 via 10.40.33.2 dev vlan33 proto bird
|
||||
10.40.216.0/21 via 10.40.217.17 dev vlan217 proto bird
|
||||
10.40.217.16/30 dev vlan217 proto kernel scope link src 10.40.217.18
|
||||
|
||||
And there was much rejoicing! Yayyyy! Well, let's have a look what we can do with this result. Since both networks are now aware of each other's routes, I'd expect I can do some tracerouting into a remote network now!
|
||||
|
||||
root@R10:/# traceroute -n 10.40.2.6
|
||||
traceroute to 10.40.2.6 (10.40.2.6), 30 hops max, 60 byte packets
|
||||
1 10.40.217.17 0.356 ms 0.319 ms 0.324 ms
|
||||
2 10.40.216.2 0.430 ms 0.427 ms 0.378 ms
|
||||
3 10.40.2.6 0.781 ms 0.724 ms 0.716 ms
|
||||
|
||||
W00t!. `R10` now knows the route to IPv4 ranges used in `AS64080`, and it seems `H6` also knows a route back to `R10`.
|
||||
|
||||
Let's try it from `H34`!
|
||||
|
||||
root@H34:/# traceroute -n 10.40.2.6
|
||||
traceroute to 10.40.2.6 (10.40.2.6), 30 hops max, 60 byte packets
|
||||
1 10.40.36.1 0.296 ms !N 0.091 ms !N *
|
||||
|
||||
Meh, that doesn't look to good. Apparently there's more work to do.
|
||||
|
||||
## Some assignments
|
||||
|
||||
Now make sure you can do the following, and answer the following questions:
|
||||
|
||||
* Configure the IPv6 BGP connection between `R3` and `R10`. IPv4 and IPv6 is handled separately by BIRD now, but the configuration for IPv6 is very similar to the configuration I showed here. Just use import all for bgp if you don't want to learn more about filtering now.
|
||||
* Explain why `10.40.217.18` or `2001:db8:40:d910::2` on `R10` can be pinged from `R1` now:
|
||||
|
||||
root@R1:/# ping6 2001:db8:40:d910::2
|
||||
PING 2001:db8:40:d910::2(2001:db8:40:d910::2) 56 data bytes
|
||||
64 bytes from 2001:db8:40:d910::2: icmp_seq=1 ttl=63 time=0.399 ms
|
||||
64 bytes from 2001:db8:40:d910::2: icmp_seq=2 ttl=63 time=0.099 ms
|
||||
^C
|
||||
--- 2001:db8:40:d910::2 ping statistics ---
|
||||
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
|
||||
rtt min/avg/max/mdev = 0.099/0.249/0.399/0.150 ms
|
||||
* Try to export a route outside of `10.0.0.0/8` over BGP and notice that the filter will actually stop that route from being propagated, while accepting the other routes. Using the `show route filtered protocol ebgp_r3` command the route should be visible, if it was pushed from `R3`.
|
||||
|
||||
------------
|
||||
|
||||
### TODO:
|
||||
|
||||
Zoom in on R3, R10 and add BGP configuration
|
||||
* add ebgp protocol
|
||||
* meh, umbrella route is not in bird routing table
|
||||
* how to add it? static proto, but adding it will result in kernel proto pushing it into FIB
|
||||
* keep route administration of ebgp peer in separate table. whoa, bird tables and protocols
|
||||
|
||||
## Intermezzo: BIRD tables, protocols, import, export
|
||||
|
||||
BIRD concepts:
|
||||
|
BIN
bgp-intro/bgp-ospf-zoom.dia
Normal file
BIN
bgp-intro/bgp-ospf-zoom.dia
Normal file
Binary file not shown.
BIN
bgp-intro/bgp-ospf-zoom.png
Normal file
BIN
bgp-intro/bgp-ospf-zoom.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
Loading…
x
Reference in New Issue
Block a user