initial checkin - a start of the generator, and some config files and overlays
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
*.json
|
||||
__pycache__/
|
||||
.peeringdb/
|
102
README.md
Normal file
102
README.md
Normal file
@ -0,0 +1,102 @@
|
||||
# IPng Networks Lab environment
|
||||
|
||||
|
||||
## High level overview
|
||||
|
||||
There's a disk image on each hypervisor called the `proto` image, which serves as the base
|
||||
image for all VMs on it. Every now and again, the proto image is updated (Debian, FRR and VPP)
|
||||
and from that base image, lab VMs are cloned from it and local filesystem overrides are put
|
||||
in place on each clone. The lab is used, and when we're done with it, we simply destroy all
|
||||
clones. This way, each time the lab is started, it is in a pristine state.
|
||||
|
||||
The `proto` image is shared among the hypervisors. Typically, maintenance will be performed
|
||||
on one of the hypervisors, and then the `proto` image is snapshotted and copied to the other
|
||||
machines.
|
||||
|
||||
### Proto maintenance
|
||||
|
||||
The main `vpp-proto` image runs on `hvn0.chbtl0.ipng.ch` with a VM called `vpp-proto`.
|
||||
When you want to refresh the image, you can
|
||||
|
||||
```
|
||||
spongebob:~$ ssh -A root@hvn0.chbtl0.ipng.ch
|
||||
|
||||
SNAP=$(date +%Y%m%d) ## 20221012
|
||||
zfs snapshot ssd-vol0/vpp-proto-disk0@${SNAP}-before
|
||||
virsh start --console vpp-proto
|
||||
|
||||
## Do the upgrades, make changes to vpp-proto's disk image
|
||||
## You can always roll back to the -before image if you'd like to revert
|
||||
|
||||
virsh shutdown --console vpp-proto
|
||||
zfs snapshot ssd-vol0/vpp-proto-disk0@${SNAP}-release
|
||||
zrepl signal wakeup vpp-proto-snapshots
|
||||
```
|
||||
|
||||
There is a `zrepl` running on this machine, which can pick up the snapshot by manually
|
||||
waking up the daemon (see the last command above). Each of the hypervisors in the fleet
|
||||
will watch this replication endpoint, and if they see new snapshots arrive, they will
|
||||
do an incremental pull of the data to their own ZFS filesystem as a snapshot. Old/current
|
||||
running labs will not be disrupted, as they will be cloned off of old snapshots.
|
||||
|
||||
You will find the image as `ssd-vol0/hvn0.chbtl0.ipng.ch/ssd-vol0/vpp-proto-disk0`:
|
||||
```
|
||||
spongebob:~$ ssh -A root@hvn0.lab.ipng.ch 'zfs list -t snap'
|
||||
NAME USED AVAIL REFER MOUNTPOINT
|
||||
ssd-vol0/hvn0.chbtl0.ipng.ch/ssd-vol0/vpp-proto-disk0@20221013-release 0B - 6.04G -
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
There are three hypervisor nodes each running one isolated lab environment:
|
||||
* hvn0.lab.ipng.ch runs VPP lab0
|
||||
* hvn1.lab.ipng.ch runs VPP lab1
|
||||
* hvn2.lab.ipng.ch runs VPP lab2
|
||||
|
||||
Now that we have a base image (in the form of `vpp-proto-disk0@$(date)-release`), we can
|
||||
make point-in-time clones of them, copy over any specifics (like IP addresses, hostname,
|
||||
SSH keys, Bird/FRR configs, etc). We do this on the lab controller `lab.ipng.ch` which:
|
||||
|
||||
1. Looks on the hypervisor to see if there is a running VM, and if there is, bails
|
||||
1. Looks on the hypervisor to see if there is an existing cloned image, and if there is bails
|
||||
1. Builds a local overlay directory using a generator and Jinja2 (ie. `build/vpp0-0/`)
|
||||
1. Creates a new cloned filesystem based off of a base `vpp-proto-disk0` snapshot on the hypervisor
|
||||
1. Mounts that filesystem
|
||||
1. Rsync's the built overlay into that filesystem
|
||||
1. Unmounts the filesystem
|
||||
1. Starts the VM using the newly built filesystem
|
||||
|
||||
Of course, the first two steps are meant to ensure we don't clobber running labs, which can
|
||||
be overridden with the `--force` flag. And when the lab is finished, it's common practice to
|
||||
shut down the VMs and destroy the clones.
|
||||
|
||||
```
|
||||
lab:~/src/ipng-lab$ ./destroy --host hvn0.lab.ipng.ch
|
||||
lab:~/src/ipng-lab$ ./generate --host hvn0.lab.ipng.ch --overlay bird
|
||||
lab:~/src/ipng-lab$ ./create --host hvn0.lab.ipng.ch --overlay bird
|
||||
```
|
||||
|
||||
### Generate
|
||||
|
||||
The generator reads input YAML files one after another merging and overriding them as it goes along,
|
||||
then for each node building a `node` dictionary alongside the `lab` and other information from the
|
||||
config files. Then, it read the `overlays` dictionary for a given --overlay type, reading all the
|
||||
template files from that overlay directory and assembling an output directory which will hold the
|
||||
per-node overrides, emitting them to the directory specified by the --build flag. It also copies in
|
||||
any per-node files (if they exist) from the overlays/$(overlay)/blobs/$(node.hostname)/ giving full
|
||||
control of the filesystem's contents.
|
||||
|
||||
### Create
|
||||
|
||||
Based on a generated directory and a lab YAML description, uses SSH to connect to the hypervisor,
|
||||
create a clone of the base `vpp-proto` snapshot, mount it locally in a staging directory, then rsync
|
||||
over the generated overlay from files from the generator output (build/$(overlay)/$(node.hostname))
|
||||
after which the directory is unmounted and the virtual machine booted from the clone.
|
||||
|
||||
If the VM is running, or there exists a clone, an error is printed and the process skips over that
|
||||
node. It's wise to run `destroy` before `create` to ensure the hypervisors are in a pristine state.
|
||||
|
||||
### Destroy
|
||||
|
||||
Ensures that both the VMs are not running (and will stop them if they are), and their filesystem
|
||||
clones are destroyed. Obviously this is the most dangerous operation of the bunch.
|
6
build/default/vpp0-0/etc/bird/bfd.conf
Normal file
6
build/default/vpp0-0/etc/bird/bfd.conf
Normal file
@ -0,0 +1,6 @@
|
||||
protocol bfd bfd1 {
|
||||
interface "e*" {
|
||||
interval 100 ms;
|
||||
multiplier 20;
|
||||
};
|
||||
}
|
19
build/default/vpp0-0/etc/bird/bird.conf
Normal file
19
build/default/vpp0-0/etc/bird/bird.conf
Normal file
@ -0,0 +1,19 @@
|
||||
router id 192.168.10.0;
|
||||
|
||||
protocol device { scan time 30; }
|
||||
protocol direct { ipv4; ipv6; check link yes; }
|
||||
protocol kernel kernel4 {
|
||||
ipv4 { import none; export where source != RTS_DEVICE; };
|
||||
learn off;
|
||||
scan time 300;
|
||||
}
|
||||
protocol kernel kernel6 {
|
||||
ipv6 { import none; export where source != RTS_DEVICE; };
|
||||
learn off;
|
||||
scan time 300;
|
||||
}
|
||||
|
||||
include "static.conf";
|
||||
include "bfd.conf";
|
||||
include "ospf.conf";
|
||||
include "ibgp.conf";
|
1
build/default/vpp0-0/etc/bird/ibgp.conf
Normal file
1
build/default/vpp0-0/etc/bird/ibgp.conf
Normal file
@ -0,0 +1 @@
|
||||
# NOTE(ipng): Not created yet
|
21
build/default/vpp0-0/etc/bird/ospf.conf
Normal file
21
build/default/vpp0-0/etc/bird/ospf.conf
Normal file
@ -0,0 +1,21 @@
|
||||
protocol ospf v2 ospf4 {
|
||||
ipv4 { export where source = RTS_DEVICE; import all; };
|
||||
area 0 {
|
||||
interface "loop0" { stub yes; };
|
||||
interface "e0" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e1" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e2" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e3" { type pointopoint; cost 5; bfd off; };
|
||||
};
|
||||
}
|
||||
|
||||
protocol ospf v3 ospf6 {
|
||||
ipv6 { export where source = RTS_DEVICE; import all; };
|
||||
area 0 {
|
||||
interface "loop0" { stub yes; };
|
||||
interface "e0" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e1" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e2" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e3" { type pointopoint; cost 5; bfd off; };
|
||||
};
|
||||
}
|
11
build/default/vpp0-0/etc/bird/static.conf
Normal file
11
build/default/vpp0-0/etc/bird/static.conf
Normal file
@ -0,0 +1,11 @@
|
||||
protocol static static4 {
|
||||
ipv4 { export all; };
|
||||
# route 192.0.2.0/24 via 10.0.0.1;
|
||||
route 192.168.10.0/24 unreachable;
|
||||
}
|
||||
|
||||
protocol static static6 {
|
||||
ipv6 { export all; };
|
||||
# route 2001:db8:cafe::/48 via 2001:db8::1;;
|
||||
route 2001:678:d78:200::/60 unreachable;
|
||||
}
|
1
build/default/vpp0-0/etc/hostname
Normal file
1
build/default/vpp0-0/etc/hostname
Normal file
@ -0,0 +1 @@
|
||||
vpp0-0
|
7
build/default/vpp0-0/etc/hosts
Normal file
7
build/default/vpp0-0/etc/hosts
Normal file
@ -0,0 +1,7 @@
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 vpp0-0.lab.ipng.ch vpp0-0
|
||||
|
||||
# The following lines are desirable for IPv6 capable hosts
|
||||
::1 localhost ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
14
build/default/vpp0-0/etc/netplan/01-netcfg.yaml
Normal file
14
build/default/vpp0-0/etc/netplan/01-netcfg.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
enp1s0:
|
||||
optional: true
|
||||
accept-ra: false
|
||||
dhcp4: false
|
||||
addresses: [ 192.168.1.80/24, 2001:678:d78:101::80/64 ]
|
||||
gateway4: 192.168.1.252
|
||||
gateway6: 2001:678:d78:101::1
|
||||
nameservers:
|
||||
addresses: [ "2001:678:d78::3", "2001:678:d78::4" ]
|
||||
search: [ "lab.ipng.ch", "ipng.ch", "ipng.nl", "rfc1918.ipng.nl" ]
|
38
build/default/vpp0-0/etc/vpp/bootstrap.vpp
Normal file
38
build/default/vpp0-0/etc/vpp/bootstrap.vpp
Normal file
@ -0,0 +1,38 @@
|
||||
set logging class linux-cp rate-limit 1000 level warn syslog-level notice
|
||||
|
||||
lcp default netns dataplane
|
||||
lcp lcp-sync on
|
||||
lcp lcp-auto-subint off
|
||||
|
||||
comment { Create a loopback interface }
|
||||
create loopback interface instance 0
|
||||
lcp create loop0 host-if loop0
|
||||
set interface state loop0 up
|
||||
set interface ip address loop0 192.168.10.0/32
|
||||
set interface ip address loop0 2001:678:d78:200::/128
|
||||
|
||||
comment { Create one LinuxCP Interface Pair for each phy }
|
||||
lcp create GigabitEthernet10/0/0 host-if e0
|
||||
lcp create GigabitEthernet10/0/1 host-if e1
|
||||
lcp create GigabitEthernet10/0/2 host-if e2
|
||||
lcp create GigabitEthernet10/0/3 host-if e3
|
||||
|
||||
comment { e0 is uplink to AS8298 }
|
||||
set interface state GigabitEthernet10/0/0 up
|
||||
set interface mtu packet 1500 GigabitEthernet10/0/0
|
||||
set interface ip address GigabitEthernet10/0/0 192.168.10.7/31
|
||||
set interface ip address GigabitEthernet10/0/0 2001:678:d78:201::00:00/112
|
||||
|
||||
comment { e1 is ptp with e0.vpp0-1 }
|
||||
set interface state GigabitEthernet10/0/1 up
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/1
|
||||
set interface ip address GigabitEthernet10/0/1 192.168.10.8/31
|
||||
set interface ip address GigabitEthernet10/0/1 2001:678:d78:201::01:00/112
|
||||
|
||||
comment { e2 is free to use }
|
||||
set interface state GigabitEthernet10/0/2 down
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/2
|
||||
|
||||
comment { e3 is free to use }
|
||||
set interface state GigabitEthernet10/0/3 down
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/3
|
6
build/default/vpp0-1/etc/bird/bfd.conf
Normal file
6
build/default/vpp0-1/etc/bird/bfd.conf
Normal file
@ -0,0 +1,6 @@
|
||||
protocol bfd bfd1 {
|
||||
interface "e*" {
|
||||
interval 100 ms;
|
||||
multiplier 20;
|
||||
};
|
||||
}
|
19
build/default/vpp0-1/etc/bird/bird.conf
Normal file
19
build/default/vpp0-1/etc/bird/bird.conf
Normal file
@ -0,0 +1,19 @@
|
||||
router id 192.168.10.1;
|
||||
|
||||
protocol device { scan time 30; }
|
||||
protocol direct { ipv4; ipv6; check link yes; }
|
||||
protocol kernel kernel4 {
|
||||
ipv4 { import none; export where source != RTS_DEVICE; };
|
||||
learn off;
|
||||
scan time 300;
|
||||
}
|
||||
protocol kernel kernel6 {
|
||||
ipv6 { import none; export where source != RTS_DEVICE; };
|
||||
learn off;
|
||||
scan time 300;
|
||||
}
|
||||
|
||||
include "static.conf";
|
||||
include "bfd.conf";
|
||||
include "ospf.conf";
|
||||
include "ibgp.conf";
|
1
build/default/vpp0-1/etc/bird/ibgp.conf
Normal file
1
build/default/vpp0-1/etc/bird/ibgp.conf
Normal file
@ -0,0 +1 @@
|
||||
# NOTE(ipng): Not created yet
|
21
build/default/vpp0-1/etc/bird/ospf.conf
Normal file
21
build/default/vpp0-1/etc/bird/ospf.conf
Normal file
@ -0,0 +1,21 @@
|
||||
protocol ospf v2 ospf4 {
|
||||
ipv4 { export where source = RTS_DEVICE; import all; };
|
||||
area 0 {
|
||||
interface "loop0" { stub yes; };
|
||||
interface "e0" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e1" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e2" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e3" { type pointopoint; cost 5; bfd off; };
|
||||
};
|
||||
}
|
||||
|
||||
protocol ospf v3 ospf6 {
|
||||
ipv6 { export where source = RTS_DEVICE; import all; };
|
||||
area 0 {
|
||||
interface "loop0" { stub yes; };
|
||||
interface "e0" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e1" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e2" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e3" { type pointopoint; cost 5; bfd off; };
|
||||
};
|
||||
}
|
11
build/default/vpp0-1/etc/bird/static.conf
Normal file
11
build/default/vpp0-1/etc/bird/static.conf
Normal file
@ -0,0 +1,11 @@
|
||||
protocol static static4 {
|
||||
ipv4 { export all; };
|
||||
# route 192.0.2.0/24 via 10.0.0.1;
|
||||
route 192.168.10.0/24 unreachable;
|
||||
}
|
||||
|
||||
protocol static static6 {
|
||||
ipv6 { export all; };
|
||||
# route 2001:db8:cafe::/48 via 2001:db8::1;;
|
||||
route 2001:678:d78:200::/60 unreachable;
|
||||
}
|
1
build/default/vpp0-1/etc/hostname
Normal file
1
build/default/vpp0-1/etc/hostname
Normal file
@ -0,0 +1 @@
|
||||
vpp0-1
|
7
build/default/vpp0-1/etc/hosts
Normal file
7
build/default/vpp0-1/etc/hosts
Normal file
@ -0,0 +1,7 @@
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 vpp0-1.lab.ipng.ch vpp0-1
|
||||
|
||||
# The following lines are desirable for IPv6 capable hosts
|
||||
::1 localhost ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
14
build/default/vpp0-1/etc/netplan/01-netcfg.yaml
Normal file
14
build/default/vpp0-1/etc/netplan/01-netcfg.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
enp1s0:
|
||||
optional: true
|
||||
accept-ra: false
|
||||
dhcp4: false
|
||||
addresses: [ 192.168.1.81/24, 2001:678:d78:101::81/64 ]
|
||||
gateway4: 192.168.1.252
|
||||
gateway6: 2001:678:d78:101::1
|
||||
nameservers:
|
||||
addresses: [ "2001:678:d78::3", "2001:678:d78::4" ]
|
||||
search: [ "lab.ipng.ch", "ipng.ch", "ipng.nl", "rfc1918.ipng.nl" ]
|
38
build/default/vpp0-1/etc/vpp/bootstrap.vpp
Normal file
38
build/default/vpp0-1/etc/vpp/bootstrap.vpp
Normal file
@ -0,0 +1,38 @@
|
||||
set logging class linux-cp rate-limit 1000 level warn syslog-level notice
|
||||
|
||||
lcp default netns dataplane
|
||||
lcp lcp-sync on
|
||||
lcp lcp-auto-subint off
|
||||
|
||||
comment { Create a loopback interface }
|
||||
create loopback interface instance 0
|
||||
lcp create loop0 host-if loop0
|
||||
set interface state loop0 up
|
||||
set interface ip address loop0 192.168.10.1/32
|
||||
set interface ip address loop0 2001:678:d78:200::1/128
|
||||
|
||||
comment { Create one LinuxCP Interface Pair for each phy }
|
||||
lcp create GigabitEthernet10/0/0 host-if e0
|
||||
lcp create GigabitEthernet10/0/1 host-if e1
|
||||
lcp create GigabitEthernet10/0/2 host-if e2
|
||||
lcp create GigabitEthernet10/0/3 host-if e3
|
||||
|
||||
comment { e0 is uplink to AS8298 }
|
||||
set interface state GigabitEthernet10/0/0 up
|
||||
set interface mtu packet 1500 GigabitEthernet10/0/0
|
||||
set interface ip address GigabitEthernet10/0/0 192.168.10.7/31
|
||||
set interface ip address GigabitEthernet10/0/0 2001:678:d78:201::00:00/112
|
||||
|
||||
comment { e1 is ptp with e0.vpp0-1 }
|
||||
set interface state GigabitEthernet10/0/1 up
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/1
|
||||
set interface ip address GigabitEthernet10/0/1 192.168.10.8/31
|
||||
set interface ip address GigabitEthernet10/0/1 2001:678:d78:201::01:00/112
|
||||
|
||||
comment { e2 is free to use }
|
||||
set interface state GigabitEthernet10/0/2 down
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/2
|
||||
|
||||
comment { e3 is free to use }
|
||||
set interface state GigabitEthernet10/0/3 down
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/3
|
6
build/default/vpp0-2/etc/bird/bfd.conf
Normal file
6
build/default/vpp0-2/etc/bird/bfd.conf
Normal file
@ -0,0 +1,6 @@
|
||||
protocol bfd bfd1 {
|
||||
interface "e*" {
|
||||
interval 100 ms;
|
||||
multiplier 20;
|
||||
};
|
||||
}
|
19
build/default/vpp0-2/etc/bird/bird.conf
Normal file
19
build/default/vpp0-2/etc/bird/bird.conf
Normal file
@ -0,0 +1,19 @@
|
||||
router id 192.168.10.2;
|
||||
|
||||
protocol device { scan time 30; }
|
||||
protocol direct { ipv4; ipv6; check link yes; }
|
||||
protocol kernel kernel4 {
|
||||
ipv4 { import none; export where source != RTS_DEVICE; };
|
||||
learn off;
|
||||
scan time 300;
|
||||
}
|
||||
protocol kernel kernel6 {
|
||||
ipv6 { import none; export where source != RTS_DEVICE; };
|
||||
learn off;
|
||||
scan time 300;
|
||||
}
|
||||
|
||||
include "static.conf";
|
||||
include "bfd.conf";
|
||||
include "ospf.conf";
|
||||
include "ibgp.conf";
|
1
build/default/vpp0-2/etc/bird/ibgp.conf
Normal file
1
build/default/vpp0-2/etc/bird/ibgp.conf
Normal file
@ -0,0 +1 @@
|
||||
# NOTE(ipng): Not created yet
|
21
build/default/vpp0-2/etc/bird/ospf.conf
Normal file
21
build/default/vpp0-2/etc/bird/ospf.conf
Normal file
@ -0,0 +1,21 @@
|
||||
protocol ospf v2 ospf4 {
|
||||
ipv4 { export where source = RTS_DEVICE; import all; };
|
||||
area 0 {
|
||||
interface "loop0" { stub yes; };
|
||||
interface "e0" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e1" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e2" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e3" { type pointopoint; cost 5; bfd off; };
|
||||
};
|
||||
}
|
||||
|
||||
protocol ospf v3 ospf6 {
|
||||
ipv6 { export where source = RTS_DEVICE; import all; };
|
||||
area 0 {
|
||||
interface "loop0" { stub yes; };
|
||||
interface "e0" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e1" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e2" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e3" { type pointopoint; cost 5; bfd off; };
|
||||
};
|
||||
}
|
11
build/default/vpp0-2/etc/bird/static.conf
Normal file
11
build/default/vpp0-2/etc/bird/static.conf
Normal file
@ -0,0 +1,11 @@
|
||||
protocol static static4 {
|
||||
ipv4 { export all; };
|
||||
# route 192.0.2.0/24 via 10.0.0.1;
|
||||
route 192.168.10.0/24 unreachable;
|
||||
}
|
||||
|
||||
protocol static static6 {
|
||||
ipv6 { export all; };
|
||||
# route 2001:db8:cafe::/48 via 2001:db8::1;;
|
||||
route 2001:678:d78:200::/60 unreachable;
|
||||
}
|
1
build/default/vpp0-2/etc/hostname
Normal file
1
build/default/vpp0-2/etc/hostname
Normal file
@ -0,0 +1 @@
|
||||
vpp0-2
|
7
build/default/vpp0-2/etc/hosts
Normal file
7
build/default/vpp0-2/etc/hosts
Normal file
@ -0,0 +1,7 @@
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 vpp0-2.lab.ipng.ch vpp0-2
|
||||
|
||||
# The following lines are desirable for IPv6 capable hosts
|
||||
::1 localhost ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
14
build/default/vpp0-2/etc/netplan/01-netcfg.yaml
Normal file
14
build/default/vpp0-2/etc/netplan/01-netcfg.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
enp1s0:
|
||||
optional: true
|
||||
accept-ra: false
|
||||
dhcp4: false
|
||||
addresses: [ 192.168.1.82/24, 2001:678:d78:101::82/64 ]
|
||||
gateway4: 192.168.1.252
|
||||
gateway6: 2001:678:d78:101::1
|
||||
nameservers:
|
||||
addresses: [ "2001:678:d78::3", "2001:678:d78::4" ]
|
||||
search: [ "lab.ipng.ch", "ipng.ch", "ipng.nl", "rfc1918.ipng.nl" ]
|
38
build/default/vpp0-2/etc/vpp/bootstrap.vpp
Normal file
38
build/default/vpp0-2/etc/vpp/bootstrap.vpp
Normal file
@ -0,0 +1,38 @@
|
||||
set logging class linux-cp rate-limit 1000 level warn syslog-level notice
|
||||
|
||||
lcp default netns dataplane
|
||||
lcp lcp-sync on
|
||||
lcp lcp-auto-subint off
|
||||
|
||||
comment { Create a loopback interface }
|
||||
create loopback interface instance 0
|
||||
lcp create loop0 host-if loop0
|
||||
set interface state loop0 up
|
||||
set interface ip address loop0 192.168.10.2/32
|
||||
set interface ip address loop0 2001:678:d78:200::2/128
|
||||
|
||||
comment { Create one LinuxCP Interface Pair for each phy }
|
||||
lcp create GigabitEthernet10/0/0 host-if e0
|
||||
lcp create GigabitEthernet10/0/1 host-if e1
|
||||
lcp create GigabitEthernet10/0/2 host-if e2
|
||||
lcp create GigabitEthernet10/0/3 host-if e3
|
||||
|
||||
comment { e0 is uplink to AS8298 }
|
||||
set interface state GigabitEthernet10/0/0 up
|
||||
set interface mtu packet 1500 GigabitEthernet10/0/0
|
||||
set interface ip address GigabitEthernet10/0/0 192.168.10.7/31
|
||||
set interface ip address GigabitEthernet10/0/0 2001:678:d78:201::00:00/112
|
||||
|
||||
comment { e1 is ptp with e0.vpp0-1 }
|
||||
set interface state GigabitEthernet10/0/1 up
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/1
|
||||
set interface ip address GigabitEthernet10/0/1 192.168.10.8/31
|
||||
set interface ip address GigabitEthernet10/0/1 2001:678:d78:201::01:00/112
|
||||
|
||||
comment { e2 is free to use }
|
||||
set interface state GigabitEthernet10/0/2 down
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/2
|
||||
|
||||
comment { e3 is free to use }
|
||||
set interface state GigabitEthernet10/0/3 down
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/3
|
6
build/default/vpp0-3/etc/bird/bfd.conf
Normal file
6
build/default/vpp0-3/etc/bird/bfd.conf
Normal file
@ -0,0 +1,6 @@
|
||||
protocol bfd bfd1 {
|
||||
interface "e*" {
|
||||
interval 100 ms;
|
||||
multiplier 20;
|
||||
};
|
||||
}
|
19
build/default/vpp0-3/etc/bird/bird.conf
Normal file
19
build/default/vpp0-3/etc/bird/bird.conf
Normal file
@ -0,0 +1,19 @@
|
||||
router id 192.168.10.3;
|
||||
|
||||
protocol device { scan time 30; }
|
||||
protocol direct { ipv4; ipv6; check link yes; }
|
||||
protocol kernel kernel4 {
|
||||
ipv4 { import none; export where source != RTS_DEVICE; };
|
||||
learn off;
|
||||
scan time 300;
|
||||
}
|
||||
protocol kernel kernel6 {
|
||||
ipv6 { import none; export where source != RTS_DEVICE; };
|
||||
learn off;
|
||||
scan time 300;
|
||||
}
|
||||
|
||||
include "static.conf";
|
||||
include "bfd.conf";
|
||||
include "ospf.conf";
|
||||
include "ibgp.conf";
|
1
build/default/vpp0-3/etc/bird/ibgp.conf
Normal file
1
build/default/vpp0-3/etc/bird/ibgp.conf
Normal file
@ -0,0 +1 @@
|
||||
# NOTE(ipng): Not created yet
|
21
build/default/vpp0-3/etc/bird/ospf.conf
Normal file
21
build/default/vpp0-3/etc/bird/ospf.conf
Normal file
@ -0,0 +1,21 @@
|
||||
protocol ospf v2 ospf4 {
|
||||
ipv4 { export where source = RTS_DEVICE; import all; };
|
||||
area 0 {
|
||||
interface "loop0" { stub yes; };
|
||||
interface "e0" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e1" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e2" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e3" { type pointopoint; cost 5; bfd off; };
|
||||
};
|
||||
}
|
||||
|
||||
protocol ospf v3 ospf6 {
|
||||
ipv6 { export where source = RTS_DEVICE; import all; };
|
||||
area 0 {
|
||||
interface "loop0" { stub yes; };
|
||||
interface "e0" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e1" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e2" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e3" { type pointopoint; cost 5; bfd off; };
|
||||
};
|
||||
}
|
11
build/default/vpp0-3/etc/bird/static.conf
Normal file
11
build/default/vpp0-3/etc/bird/static.conf
Normal file
@ -0,0 +1,11 @@
|
||||
protocol static static4 {
|
||||
ipv4 { export all; };
|
||||
# route 192.0.2.0/24 via 10.0.0.1;
|
||||
route 192.168.10.0/24 unreachable;
|
||||
}
|
||||
|
||||
protocol static static6 {
|
||||
ipv6 { export all; };
|
||||
# route 2001:db8:cafe::/48 via 2001:db8::1;;
|
||||
route 2001:678:d78:200::/60 unreachable;
|
||||
}
|
1
build/default/vpp0-3/etc/hostname
Normal file
1
build/default/vpp0-3/etc/hostname
Normal file
@ -0,0 +1 @@
|
||||
vpp0-3
|
7
build/default/vpp0-3/etc/hosts
Normal file
7
build/default/vpp0-3/etc/hosts
Normal file
@ -0,0 +1,7 @@
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 vpp0-3.lab.ipng.ch vpp0-3
|
||||
|
||||
# The following lines are desirable for IPv6 capable hosts
|
||||
::1 localhost ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
14
build/default/vpp0-3/etc/netplan/01-netcfg.yaml
Normal file
14
build/default/vpp0-3/etc/netplan/01-netcfg.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
enp1s0:
|
||||
optional: true
|
||||
accept-ra: false
|
||||
dhcp4: false
|
||||
addresses: [ 192.168.1.83/24, 2001:678:d78:101::83/64 ]
|
||||
gateway4: 192.168.1.252
|
||||
gateway6: 2001:678:d78:101::1
|
||||
nameservers:
|
||||
addresses: [ "2001:678:d78::3", "2001:678:d78::4" ]
|
||||
search: [ "lab.ipng.ch", "ipng.ch", "ipng.nl", "rfc1918.ipng.nl" ]
|
38
build/default/vpp0-3/etc/vpp/bootstrap.vpp
Normal file
38
build/default/vpp0-3/etc/vpp/bootstrap.vpp
Normal file
@ -0,0 +1,38 @@
|
||||
set logging class linux-cp rate-limit 1000 level warn syslog-level notice
|
||||
|
||||
lcp default netns dataplane
|
||||
lcp lcp-sync on
|
||||
lcp lcp-auto-subint off
|
||||
|
||||
comment { Create a loopback interface }
|
||||
create loopback interface instance 0
|
||||
lcp create loop0 host-if loop0
|
||||
set interface state loop0 up
|
||||
set interface ip address loop0 192.168.10.3/32
|
||||
set interface ip address loop0 2001:678:d78:200::3/128
|
||||
|
||||
comment { Create one LinuxCP Interface Pair for each phy }
|
||||
lcp create GigabitEthernet10/0/0 host-if e0
|
||||
lcp create GigabitEthernet10/0/1 host-if e1
|
||||
lcp create GigabitEthernet10/0/2 host-if e2
|
||||
lcp create GigabitEthernet10/0/3 host-if e3
|
||||
|
||||
comment { e0 is uplink to AS8298 }
|
||||
set interface state GigabitEthernet10/0/0 up
|
||||
set interface mtu packet 1500 GigabitEthernet10/0/0
|
||||
set interface ip address GigabitEthernet10/0/0 192.168.10.7/31
|
||||
set interface ip address GigabitEthernet10/0/0 2001:678:d78:201::00:00/112
|
||||
|
||||
comment { e1 is ptp with e0.vpp0-1 }
|
||||
set interface state GigabitEthernet10/0/1 up
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/1
|
||||
set interface ip address GigabitEthernet10/0/1 192.168.10.8/31
|
||||
set interface ip address GigabitEthernet10/0/1 2001:678:d78:201::01:00/112
|
||||
|
||||
comment { e2 is free to use }
|
||||
set interface state GigabitEthernet10/0/2 down
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/2
|
||||
|
||||
comment { e3 is free to use }
|
||||
set interface state GigabitEthernet10/0/3 down
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/3
|
21
config/common/generic.yaml
Normal file
21
config/common/generic.yaml
Normal file
@ -0,0 +1,21 @@
|
||||
pubkeys:
|
||||
root:
|
||||
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8X6oRdLn7PckWIRL+Fgp46qN+fglQLBJIvPHJ2P277v4tx/qlELaT8w45YyEPrUZ4XbbNIB4P59H63wPxIpk/d15k0C7Zx3kTESaEQuts3fne3ZFmrWm0dLD2yDTiB0zCraiQ5a0w++xuGEC3wdWPV+FHZh5Ea+WCd91g2xXPHJeosAQzBBBBaC9Shhx91h6lbCm4evvgqLnwt7JgnI2N4w2qr13lDDaRD4BXfyFrtLSTdhBgYEaFnUd6Afz5ilfDYXQW/yTSHZOIQ/vNVFpFxYrtmwHDdrSMiDpz0FE/4LLBG/rFl2VvRTmTEyjvwpGpEVaivMOLo/jRc3TA7jKB pim@ipng.nl"
|
||||
- "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKDP/hLZusPNfKTy3t9bbbOHyczX+UACc4rYstc3QEDBDfxBnCZcMKN5Mv10o+q/+ap7wyFhONlz/qcUhEMbI1k="
|
||||
ipng:
|
||||
- "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC8X6oRdLn7PckWIRL+Fgp46qN+fglQLBJIvPHJ2P277v4tx/qlELaT8w45YyEPrUZ4XbbNIB4P59H63wPxIpk/d15k0C7Zx3kTESaEQuts3fne3ZFmrWm0dLD2yDTiB0zCraiQ5a0w++xuGEC3wdWPV+FHZh5Ea+WCd91g2xXPHJeosAQzBBBBaC9Shhx91h6lbCm4evvgqLnwt7JgnI2N4w2qr13lDDaRD4BXfyFrtLSTdhBgYEaFnUd6Afz5ilfDYXQW/yTSHZOIQ/vNVFpFxYrtmwHDdrSMiDpz0FE/4LLBG/rFl2VvRTmTEyjvwpGpEVaivMOLo/jRc3TA7jKB pim@ipng.nl"
|
||||
- "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKDP/hLZusPNfKTy3t9bbbOHyczX+UACc4rYstc3QEDBDfxBnCZcMKN5Mv10o+q/+ap7wyFhONlz/qcUhEMbI1k="
|
||||
|
||||
|
||||
overlays:
|
||||
default:
|
||||
path: overlays/bird/
|
||||
build: build/default/
|
||||
|
||||
bird:
|
||||
path: overlays/bird/
|
||||
build: build/bird/
|
||||
|
||||
frr:
|
||||
path: overlays/frr/
|
||||
build: build/frr/
|
22
config/hvn0.lab.ipng.ch.yaml
Normal file
22
config/hvn0.lab.ipng.ch.yaml
Normal file
@ -0,0 +1,22 @@
|
||||
lab:
|
||||
id: 0
|
||||
mgmt:
|
||||
ipv4: 192.168.1.80/24
|
||||
ipv6: 2001:678:d78:101::80/64
|
||||
gw4: 192.168.1.252
|
||||
gw6: 2001:678:d78:101::1
|
||||
ipv4: 192.168.10.0/24
|
||||
ipv6: 2001:678:d78:200::/60
|
||||
hypervisor: hvn0.lab.ipng.ch
|
||||
nodes: 4
|
||||
|
||||
## for i in lab.nodes; do
|
||||
# node:
|
||||
# hostname: "vpp" + lab.id + "-" + i
|
||||
# id: i
|
||||
# mgmt:
|
||||
# ipv4: lab.mgmt.ipv4 + node.id
|
||||
# ipv6: lab.mgmt.ipv6 + node.id
|
||||
# loopback:
|
||||
# ipv4: lab.ipv4 + node.id + "/32"
|
||||
# ipv6: lab.ipv6 + node.id + "/128"
|
270
generate
Executable file
270
generate
Executable file
@ -0,0 +1,270 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Labs for IPng Networks
|
||||
|
||||
(c) 2022- Pim van Pelt <pim@ipng.nl>
|
||||
|
||||
"""
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from jinja2_ansible_filters import AnsibleCoreFiltersExtension
|
||||
|
||||
import hiyapyco
|
||||
import traceback
|
||||
import os
|
||||
import sys
|
||||
import pprint
|
||||
import logging
|
||||
import ipaddress
|
||||
import re
|
||||
|
||||
try:
|
||||
import argparse
|
||||
except ImportError:
|
||||
print("ERROR: install argparse manually")
|
||||
print("HINT: sudo pip install argparse")
|
||||
sys.exit(2)
|
||||
|
||||
log = logging.getLogger("generate")
|
||||
log.setLevel(logging.INFO)
|
||||
formatter = logging.Formatter(
|
||||
"[%(levelname)-8s] %(name)17s - %(funcName)-15s: %(message)s"
|
||||
)
|
||||
ch = logging.StreamHandler()
|
||||
ch.setLevel(logging.DEBUG)
|
||||
ch.setFormatter(formatter)
|
||||
log.addHandler(ch)
|
||||
|
||||
|
||||
def toyaml(d, indent=0, result=""):
|
||||
for key, value in d.items():
|
||||
result += " " * indent + str(key) + ": "
|
||||
if isinstance(value, dict):
|
||||
result = toyaml(value, indent + 2, result + "\n")
|
||||
else:
|
||||
if isinstance(value, str) and [
|
||||
e for e in [" ", ":", "{", "}", "[", "]", "#"] if e in value
|
||||
]:
|
||||
result += "'" + str(value) + "'\n"
|
||||
else:
|
||||
result += str(value) + "\n"
|
||||
return result
|
||||
|
||||
|
||||
def render(tpl_path, data, trim=True):
|
||||
path, filename = os.path.split(tpl_path)
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(path or "./"), extensions=[AnsibleCoreFiltersExtension]
|
||||
)
|
||||
env.trim_blocks = trim
|
||||
env.lstrip_blocks = trim
|
||||
env.rstrip_blocks = trim
|
||||
env.filters["toyaml"] = toyaml
|
||||
|
||||
return env.get_template(filename).render(data)
|
||||
|
||||
|
||||
def tpl2fn(tpl, prefix):
|
||||
fn = tpl[len(prefix) :]
|
||||
if fn.endswith(".j2"):
|
||||
fn = fn[:-3]
|
||||
return fn
|
||||
|
||||
|
||||
def find(file_or_dir_list):
|
||||
log.info("Finding templates in %s" % file_or_dir_list)
|
||||
ret = {}
|
||||
for e in file_or_dir_list:
|
||||
if e.startswith("_"):
|
||||
continue
|
||||
if os.path.isfile(e):
|
||||
ret[e] = tpl2fn(e, e)
|
||||
elif os.path.isdir(e):
|
||||
for root, dirnames, filenames in os.walk(e):
|
||||
for filename in filenames:
|
||||
if filename.startswith("_"):
|
||||
continue
|
||||
tpl = os.path.join(root, filename)
|
||||
ret[tpl] = tpl2fn(tpl, e)
|
||||
|
||||
log.debug("Templates: %s" % ret)
|
||||
return ret
|
||||
|
||||
|
||||
def generate(templates, data, debug=False):
|
||||
output = {}
|
||||
for tpl, fn in templates.items():
|
||||
log.info("Rendering %s into %s" % (tpl, fn))
|
||||
try:
|
||||
output[fn] = render(tpl, data)
|
||||
except:
|
||||
log.error("Could not render %s!" % tpl)
|
||||
if debug:
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
return None
|
||||
return output
|
||||
|
||||
|
||||
def emit(output, outdir):
|
||||
log.debug("Emitting to %s" % outdir)
|
||||
for fn, contents in output.items():
|
||||
if outdir == "-":
|
||||
log.info("Emitting %s" % fn)
|
||||
print(contents)
|
||||
continue
|
||||
|
||||
outfile = os.path.join(outdir, fn)
|
||||
log.info("Emitting %s into %s" % (fn, outfile))
|
||||
basedir = os.path.dirname(outfile)
|
||||
os.makedirs(basedir, exist_ok=True)
|
||||
f = open(outfile, "w")
|
||||
f.write(contents)
|
||||
f.close()
|
||||
|
||||
|
||||
def prune(output, outdir):
|
||||
if outdir == "-":
|
||||
log.info("Skipping pruning, output is stdout")
|
||||
return True
|
||||
|
||||
for root, dirnames, filenames in os.walk(outdir):
|
||||
for filename in filenames:
|
||||
fn = os.path.join(root, filename) # build/frggh0.ipng.ch/bird/bird.conf
|
||||
rel_fn = fn.replace(outdir, "") # /bird/bird.conf
|
||||
if rel_fn[0] == "/":
|
||||
rel_fn = rel_fn[1:] # bird/bird.conf
|
||||
if not rel_fn in output:
|
||||
log.info("Pruning file %s (%s)" % (rel_fn, fn))
|
||||
os.remove(fn)
|
||||
|
||||
for root, dirnames, filenames in os.walk(outdir):
|
||||
for dirname in dirnames:
|
||||
dn = os.path.join(root, dirname) # build/frggh0.ipng.ch/bird/empty
|
||||
if not os.listdir(dn):
|
||||
log.info("Pruning dir %s" % (dn))
|
||||
os.rmdir(dn)
|
||||
|
||||
|
||||
def create_node(lab, node_id):
|
||||
v4_base, v4_plen = lab["mgmt"]["ipv4"].split("/")
|
||||
v6_base, v6_plen = lab["mgmt"]["ipv6"].split("/")
|
||||
lo4_base = lab["ipv4"].split("/")[0]
|
||||
lo6_base = lab["ipv6"].split("/")[0]
|
||||
ret = {
|
||||
"hostname": "vpp%d-%d" % (lab["id"], node_id),
|
||||
"id": node_id,
|
||||
"mgmt": {
|
||||
"ipv4": "%s/%s"
|
||||
% (
|
||||
ipaddress.IPv4Address(v4_base) + lab["nodes"] * lab["id"] + node_id,
|
||||
v4_plen,
|
||||
),
|
||||
"ipv6": "%s/%s"
|
||||
% (
|
||||
ipaddress.IPv6Address(v6_base) + lab["nodes"] * lab["id"] + node_id,
|
||||
v6_plen,
|
||||
),
|
||||
"gw4": lab["mgmt"]["gw4"],
|
||||
"gw6": lab["mgmt"]["gw6"],
|
||||
},
|
||||
"loopback": {
|
||||
"ipv4": "%s/32" % (ipaddress.IPv4Address(lo4_base) + node_id),
|
||||
"ipv6": "%s/128" % (ipaddress.IPv6Address(lo6_base) + node_id),
|
||||
},
|
||||
}
|
||||
return ret
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
|
||||
parser.add_argument(
|
||||
"-d", dest="debug", action="store_true", help="""Enable debug"""
|
||||
)
|
||||
parser.add_argument(
|
||||
"-q", dest="quiet", action="store_true", help="""Quiet output"""
|
||||
)
|
||||
parser.add_argument("--host", dest="hostname", help="""Hostname to configure for""")
|
||||
parser.add_argument(
|
||||
"--yaml",
|
||||
dest="yamldata",
|
||||
default=["config/common/generic.yaml"],
|
||||
type=str,
|
||||
nargs="*",
|
||||
help="""Location of YAML data file(s)""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--overlay",
|
||||
dest="overlay",
|
||||
default="default",
|
||||
type=str,
|
||||
help="""Type of lab setup (defined in config/common/generic.yaml 'overlays' dictionary, defaults to 'default')""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
dest="output",
|
||||
type=str,
|
||||
default=None,
|
||||
help="Output directory (default: overlay.build)",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.debug and args.quiet:
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
if not args.hostname:
|
||||
parser.print_help()
|
||||
return
|
||||
|
||||
if args.quiet:
|
||||
log.setLevel(logging.ERROR)
|
||||
elif args.debug:
|
||||
log.setLevel(logging.DEBUG)
|
||||
|
||||
yamldata = "config/%s.yaml" % args.hostname
|
||||
if not os.path.exists(yamldata):
|
||||
log.error("Can't read config file %s" % yamldata)
|
||||
return
|
||||
log.info("Generating host %s" % (args.hostname))
|
||||
|
||||
# Assemble the YAML dictionary
|
||||
yamldata = args.yamldata + [yamldata]
|
||||
log.debug("YAML data: %s" % yamldata)
|
||||
data = hiyapyco.load(*yamldata, method=hiyapyco.METHOD_MERGE, interpolate=True)
|
||||
if args.debug:
|
||||
log.debug("YAML merged configuration")
|
||||
print(hiyapyco.dump(data, default_flow_style=False))
|
||||
|
||||
if not args.overlay in data["overlays"]:
|
||||
log.error("Overlay not defined, bailing.")
|
||||
return
|
||||
|
||||
# Assemble a dictionary of tpl=>fn
|
||||
overlay = data["overlays"][args.overlay]
|
||||
template_root = overlay["path"] + "templates/"
|
||||
templates = find([template_root])
|
||||
|
||||
for node_id in range(data["lab"]["nodes"]):
|
||||
log.info("Generating for node %d" % node_id)
|
||||
data["node"] = create_node(data["lab"], node_id)
|
||||
log.debug("node: %s" % data["node"])
|
||||
|
||||
# Assemble a dictionary of fn=>output
|
||||
build = generate(templates, data, args.debug)
|
||||
if not build:
|
||||
return
|
||||
|
||||
# Emit the output (fn=>output)
|
||||
if not args.output and "build" in overlay:
|
||||
output = overlay["build"] + data["node"]["hostname"]
|
||||
else:
|
||||
output = "-"
|
||||
emit(build, output)
|
||||
|
||||
# Remove all files/dirs not in (fn=>output)
|
||||
# prune(output, args.output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
6
overlays/bird/templates/etc/bird/bfd.conf.j2
Normal file
6
overlays/bird/templates/etc/bird/bfd.conf.j2
Normal file
@ -0,0 +1,6 @@
|
||||
protocol bfd bfd1 {
|
||||
interface "e*" {
|
||||
interval 100 ms;
|
||||
multiplier 20;
|
||||
};
|
||||
}
|
19
overlays/bird/templates/etc/bird/bird.conf.j2
Normal file
19
overlays/bird/templates/etc/bird/bird.conf.j2
Normal file
@ -0,0 +1,19 @@
|
||||
router id {{ node.loopback.ipv4.split("/")[0] }};
|
||||
|
||||
protocol device { scan time 30; }
|
||||
protocol direct { ipv4; ipv6; check link yes; }
|
||||
protocol kernel kernel4 {
|
||||
ipv4 { import none; export where source != RTS_DEVICE; };
|
||||
learn off;
|
||||
scan time 300;
|
||||
}
|
||||
protocol kernel kernel6 {
|
||||
ipv6 { import none; export where source != RTS_DEVICE; };
|
||||
learn off;
|
||||
scan time 300;
|
||||
}
|
||||
|
||||
include "static.conf";
|
||||
include "bfd.conf";
|
||||
include "ospf.conf";
|
||||
include "ibgp.conf";
|
1
overlays/bird/templates/etc/bird/ibgp.conf.j2
Normal file
1
overlays/bird/templates/etc/bird/ibgp.conf.j2
Normal file
@ -0,0 +1 @@
|
||||
# NOTE(ipng): Not created yet
|
21
overlays/bird/templates/etc/bird/ospf.conf.j2
Normal file
21
overlays/bird/templates/etc/bird/ospf.conf.j2
Normal file
@ -0,0 +1,21 @@
|
||||
protocol ospf v2 ospf4 {
|
||||
ipv4 { export where source = RTS_DEVICE; import all; };
|
||||
area 0 {
|
||||
interface "loop0" { stub yes; };
|
||||
interface "e0" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e1" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e2" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e3" { type pointopoint; cost 5; bfd off; };
|
||||
};
|
||||
}
|
||||
|
||||
protocol ospf v3 ospf6 {
|
||||
ipv6 { export where source = RTS_DEVICE; import all; };
|
||||
area 0 {
|
||||
interface "loop0" { stub yes; };
|
||||
interface "e0" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e1" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e2" { type pointopoint; cost 5; bfd off; };
|
||||
interface "e3" { type pointopoint; cost 5; bfd off; };
|
||||
};
|
||||
}
|
11
overlays/bird/templates/etc/bird/static.conf.j2
Normal file
11
overlays/bird/templates/etc/bird/static.conf.j2
Normal file
@ -0,0 +1,11 @@
|
||||
protocol static static4 {
|
||||
ipv4 { export all; };
|
||||
# route 192.0.2.0/24 via 10.0.0.1;
|
||||
route {{lab.ipv4}} unreachable;
|
||||
}
|
||||
|
||||
protocol static static6 {
|
||||
ipv6 { export all; };
|
||||
# route 2001:db8:cafe::/48 via 2001:db8::1;;
|
||||
route {{lab.ipv6}} unreachable;
|
||||
}
|
1
overlays/bird/templates/etc/hostname.j2
Normal file
1
overlays/bird/templates/etc/hostname.j2
Normal file
@ -0,0 +1 @@
|
||||
{{ node.hostname }}
|
7
overlays/bird/templates/etc/hosts.j2
Normal file
7
overlays/bird/templates/etc/hosts.j2
Normal file
@ -0,0 +1,7 @@
|
||||
127.0.0.1 localhost
|
||||
127.0.1.1 {{node.hostname}}.lab.ipng.ch {{node.hostname}}
|
||||
|
||||
# The following lines are desirable for IPv6 capable hosts
|
||||
::1 localhost ip6-localhost ip6-loopback
|
||||
ff02::1 ip6-allnodes
|
||||
ff02::2 ip6-allrouters
|
14
overlays/bird/templates/etc/netplan/01-netcfg.yaml.j2
Normal file
14
overlays/bird/templates/etc/netplan/01-netcfg.yaml.j2
Normal file
@ -0,0 +1,14 @@
|
||||
network:
|
||||
version: 2
|
||||
renderer: networkd
|
||||
ethernets:
|
||||
enp1s0:
|
||||
optional: true
|
||||
accept-ra: false
|
||||
dhcp4: false
|
||||
addresses: [ {{node.mgmt.ipv4}}, {{node.mgmt.ipv6}} ]
|
||||
gateway4: {{lab.mgmt.gw4}}
|
||||
gateway6: {{lab.mgmt.gw6}}
|
||||
nameservers:
|
||||
addresses: [ "2001:678:d78::3", "2001:678:d78::4" ]
|
||||
search: [ "lab.ipng.ch", "ipng.ch", "ipng.nl", "rfc1918.ipng.nl" ]
|
38
overlays/bird/templates/etc/vpp/bootstrap.vpp.j2
Normal file
38
overlays/bird/templates/etc/vpp/bootstrap.vpp.j2
Normal file
@ -0,0 +1,38 @@
|
||||
set logging class linux-cp rate-limit 1000 level warn syslog-level notice
|
||||
|
||||
lcp default netns dataplane
|
||||
lcp lcp-sync on
|
||||
lcp lcp-auto-subint off
|
||||
|
||||
comment { Create a loopback interface }
|
||||
create loopback interface instance 0
|
||||
lcp create loop0 host-if loop0
|
||||
set interface state loop0 up
|
||||
set interface ip address loop0 {{ node.loopback.ipv4 }}
|
||||
set interface ip address loop0 {{ node.loopback.ipv6 }}
|
||||
|
||||
comment { Create one LinuxCP Interface Pair for each phy }
|
||||
lcp create GigabitEthernet10/0/0 host-if e0
|
||||
lcp create GigabitEthernet10/0/1 host-if e1
|
||||
lcp create GigabitEthernet10/0/2 host-if e2
|
||||
lcp create GigabitEthernet10/0/3 host-if e3
|
||||
|
||||
comment { e0 is uplink to AS8298 }
|
||||
set interface state GigabitEthernet10/0/0 up
|
||||
set interface mtu packet 1500 GigabitEthernet10/0/0
|
||||
set interface ip address GigabitEthernet10/0/0 192.168.10.7/31
|
||||
set interface ip address GigabitEthernet10/0/0 2001:678:d78:201::00:00/112
|
||||
|
||||
comment { e1 is ptp with e0.vpp0-1 }
|
||||
set interface state GigabitEthernet10/0/1 up
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/1
|
||||
set interface ip address GigabitEthernet10/0/1 192.168.10.8/31
|
||||
set interface ip address GigabitEthernet10/0/1 2001:678:d78:201::01:00/112
|
||||
|
||||
comment { e2 is free to use }
|
||||
set interface state GigabitEthernet10/0/2 down
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/2
|
||||
|
||||
comment { e3 is free to use }
|
||||
set interface state GigabitEthernet10/0/3 down
|
||||
set interface mtu packet 9000 GigabitEthernet10/0/3
|
Reference in New Issue
Block a user