- ansible-frr
An Ansible role to install/configure FRR
NOTE: FRRouting (FRR) is an IP routing protocol suite for Linux and Unix platforms which includes protocol daemons for BGP, IS-IS, LDP, OSPF, PIM, and RIP.
Below is an example of Route Maps Configuration:
frr_route_map:
RTBH:
permit 10:
interface: blackhole
prefix_list: Bad_IPs
origin: igp
community: '12345:100'
RTBH_IN:
deny 10: []
Below is an example of Prefix List Configuration:
frr_prefix_list:
Bad_IPs:
05 permit:
prefix: 192.168.88.0/24
match: ge 32
10 permit:
prefix: 172.16.0.0/16
match: le 32
frr_prefix_list_v6:
Bad_IPs:
05 permit:
prefix: 1234:5678::/32
match: ge 128
Below is an example
frr_access_list:
- '10 permit 10.10.10.21/32'
- '10 permit 192.168.0.0/17'
- '101 permit ip 10.0.0.0 0.0.0.255 any'
Protocol | Implemented | Notes |
---|---|---|
BGP | X | Only initial config |
OSPF | X | Only initial config |
STATIC | X | Only initial config |
To enable BGP routing, make sure that bgpd: true
is configured under:
frr_daemons:
bgpd: false
isisd: false
ldpd: false
nhrpd: false
ospf6d: false
ospfd: false
pimd: false
ripd: false
ripngd: false
zebra: true
In order to configure BGP, define the following based on your requirements:
frr_bgp:
asns:
65000:
log_neighbor_changes: true
timers: '3 9'
neighbors:
192.168.250.11:
asn: 65000
default_originate: false
description: node1
next_hop_self: true
timers_connect: 5
192.168.250.12:
asn: 65000
default_originate: false
description: node2
next_hop_self: true
password: secret
192.168.250.12:
asn: 66000
description: far_away
multihop: 255
networks:
- "{{ frr_router_id }}/32"
- "{{ hostvars[inventory_hostname]['ansible_enp0s8']['ipv4']['address'] }}/24"
redistribute:
- bgp
- connected
- kernel
- ospf
- static
redistribute_v6:
- bgp
- connected
- kernel
Below is an example of a BGP configuration:
frr_bgp:
asns:
65000:
log_neighbor_changes: true
neighbors:
192.168.250.11:
asn: 65000
default_originate: false
description: node1
next_hop_self: true
192.168.250.12:
asn: 65000
default_originate: false
description: node2
next_hop_self: true
"::1":
asn: 65000
default_originate: false
description: node1
next_hop_self: true
adress_family: "ipv6 unicast"
networks:
- "{{ frr_router_id }}/32"
- "{{ hostvars[inventory_hostname]['ansible_enp0s8']['ipv4']['address'] }}/24"
- "{{ hostvars[inventory_hostname]['ansible_enp0s9']['ipv4']['address'] }}/24"
- "{{ hostvars[inventory_hostname]['ansible_enp0s10']['ipv4']['address'] }}/24"
- "{{ hostvars[inventory_hostname]['ansible_enp0s16']['ipv4']['address'] }}/24"
networks_v6:
- "1::3/64"
Below is an example of a BGP summary based on the above configuration:
BGP table version is 13, local router ID is 1.1.1.1
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
i internal, r RIB-failure, S Stale, R Removed
Origin codes: i - IGP, e - EGP, ? - incomplete
Network Next Hop Metric LocPrf Weight Path
*> 1.1.1.1/32 0.0.0.0 0 32768 i
*>i2.2.2.2/32 192.168.250.11 0 100 0 i
*>i3.3.3.3/32 192.168.250.12 0 100 0 i
*> 192.168.10.0 0.0.0.0 0 32768 i
*>i192.168.11.0 192.168.250.11 0 100 0 i
*>i192.168.12.0 192.168.250.12 0 100 0 i
*> 192.168.20.0 0.0.0.0 0 32768 i
*>i192.168.21.0 192.168.250.11 0 100 0 i
*>i192.168.22.0 192.168.250.12 0 100 0 i
*> 192.168.30.0 0.0.0.0 0 32768 i
*>i192.168.31.0 192.168.250.11 0 100 0 i
*>i192.168.32.0 192.168.250.12 0 100 0 i
* i192.168.250.0 192.168.250.11 0 100 0 i
* i 192.168.250.12 0 100 0 i
*> 0.0.0.0 0 32768 i
Displayed 13 routes and 15 total paths
To enable OSPF routing, make sure that ospfd: true
is configured under:
frr_daemons:
bgpd: false
isisd: false
ldpd: false
nhrpd: false
ospf6d: false
ospfd: false
pimd: false
ripd: false
ripngd: false
zebra: true
In order to configure OSPF, define the following based on your requirements:
frr_ospf:
areas:
0:
networks:
- "{{ frr_router_id }}/32"
1:
networks:
- "{{ hostvars[inventory_hostname]['ansible_enp0s8']['ipv4']['address'] }}/24"
auth: true
2:
networks:
- "{{ hostvars[inventory_hostname]['ansible_enp0s9']['ipv4']['address'] }}/24"
type: nssa
log_adjacency_changes: true
passive_interfaces: # A list of interfaces to set passive
- default
redistribute: # A list of protocols to redistribute
- bgp
- connected
- kernel
- ospf
- static
distribute_list:
- name: 10
dir: out
protocol: connected
In order to configure static routes, define the following based on your requirements:
frr_static: # A dict. key = destination, value = nexthop
10.0.0.0/8: 192.168.1.1
1.1.1.1: 192.168.1.1
1.1.1.2: blackhole
frr_static_v6: # A dict. key = destination, value = nexthop
2001:0db8:85a3:8a2e::/64 2001::1
frr_interfaces: # A dict. key = iface name, value = iface data
lo:
ip: 10.0.0.0/32 # ip can be a single value or list
ipv6: 2001:0db8:85a3:8a2e::1/64 # ipv6 can be a single value or list
description: loopback
eth0:
ip: # ip can be a single value or list
- 10.0.0.0/32
- 172.16.0.0/32
ipv6: # ipv6 can be a single value or list
- 2001:0db8:85a3:8a2e::1/64
- 2001:0db8:85a3:8a2e::2/64
auth:
id: 1
key: supersecret
other:
- "no ipv6 nd suppress-ra"
- "link-detect"
Included is a ready to go BGP CLOS fabric based on the below diagram. Ready to be spun up in Vagrant.
Node | Function | ASN | Loopback | enp0s8 | enp0s9 | enp0s10 | enp0s16 | enp0s17 |
---|---|---|---|---|---|---|---|---|
Spine1 | Spine | 65011 | 10.0.10.1/32 | 192.168.250.11/24 | 192.168.1.0/31 | 192.168.1.2/31 | 192.168.1.4/31 | 192.168.1.6/31 |
Spine2 | Spine | 65012 | 10.0.10.2/32 | 192.168.250.12/24 | 192.168.2.0/31 | 192.168.2.2/31 | 192.168.2.4/31 | 192.168.2.6/31 |
Leaf1 | Leaf | 65021 | 10.0.20.3/32 | 192.168.250.21/24 | 192.168.1.1/31 | 192.168.10.0/31 | 192.168.2.5/31 | |
Leaf2 | Leaf | 65022 | 10.0.20.4/32 | 192.168.250.22/24 | 192.168.1.3/31 | 192.168.10.2/31 | 192.168.2.7/31 | |
Leaf3 | Leaf | 65023 | 10.0.20.5/32 | 192.168.250.23/24 | 192.168.1.5/31 | 192.168.20.0/31 | 192.168.2.1/31 | |
Leaf4 | Leaf | 65024 | 10.0.20.6/32 | 192.168.250.24/24 | 192.168.1.7/31 | 192.168.20.2/31 | 192.168.2.3/31 | |
Compute1 | Compute | 65031 | 10.0.30.1/32 | 192.168.250.31/24 | 192.168.10.1/31 | 192.168.10.3/31 | ||
Compute2 | Compute | 65032 | 10.0.30.2/32 | 192.168.250.32/24 | 192.168.20.1/31 | 192.168.20.3/31 |
In order to spin up this environment simply do the following:
cd Vagrant
vagrant up
Once all of the nodes are spun up your routing topology should be similar to below:
sh ip route bgp
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, P - PIM, N - NHRP, T - Table,
v - VNC, V - VNC-Direct,
> - selected route, * - FIB route
B>* 10.0.10.2/32 [20/0] via 192.168.1.3, enp0s10, 02:53:22
B>* 10.0.20.3/32 [20/0] via 192.168.1.1, enp0s9, 02:43:37
B>* 10.0.20.4/32 [20/0] via 192.168.1.3, enp0s10, 02:53:22
B>* 10.0.20.5/32 [20/0] via 192.168.1.5, enp0s16, 02:53:22
B>* 10.0.20.6/32 [20/0] via 192.168.1.7, enp0s17, 02:53:22
B>* 10.0.30.1/32 [20/0] via 192.168.1.3, enp0s10, 02:53:22
B>* 10.0.30.2/32 [20/0] via 192.168.1.7, enp0s17, 02:53:22
B>* 192.168.2.0/31 [20/0] via 192.168.1.5, enp0s16, 02:53:22
B>* 192.168.2.2/31 [20/0] via 192.168.1.7, enp0s17, 02:53:22
B>* 192.168.2.4/31 [20/0] via 192.168.1.1, enp0s9, 02:43:37
B>* 192.168.2.6/31 [20/0] via 192.168.1.3, enp0s10, 02:53:22
B>* 192.168.10.0/31 [20/0] via 192.168.1.1, enp0s9, 02:43:37
B>* 192.168.10.2/31 [20/0] via 192.168.1.3, enp0s10, 02:53:22
B>* 192.168.20.0/31 [20/0] via 192.168.1.5, enp0s16, 02:53:22
B>* 192.168.20.2/31 [20/0] via 192.168.1.7, enp0s17, 02:53:22
We have included some basic monitoring of BGP stats and system stats. We are
spinning up an InfluxDB
container on compute1
and a Grafana
container on
compute2
as part of the provisioning. All of the VMs are running
Telegraf
which is running some scripts to capture BGP stats and then sending
to InfluxDB
. We can then visualize the status using Grafana
by connecting to
the Grafana Web UI which again, is a Docker
container running on compute2
.
Using your browser of choice connect to the Grafana Web UI
and use admin:admin
to login.
Add InfluxDB as a data source by providing the following in the config:
Name:
influxdbType:
InfluxDBURL:
http://192.168.250.31:8086Database:
telegraf
We have included some Grafana
dashboards which can be imported in the
Vagrant/dashboards folder.
When you are done testing you can simply tear everything down by:
scripts/cleanup.sh
NOTE: FRR is unable to be downgraded from 6.0.2 using this role.
You can upgrade or downgrade FRR by setting the following variable:
frr_version: 6.0.2
from frr_version: 6.0
MIT
Larry Smith Jr.