0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-10-18 09:58:43 +00:00

Flock tests: create simple environment

This is a first try on adapting Flock on cf-bgp-secondary
from bird-tools.
This commit is contained in:
Maria Matejka 2024-07-10 12:44:53 +02:00
parent e787a9210f
commit 5aaa8ea226
3 changed files with 220 additions and 0 deletions

View File

@ -0,0 +1,23 @@
log "bird.log" all;
router id 2;
ipv6 table master6;
protocol device {
scan time 10;
}
protocol kernel kernel6 {
scan time 10;
ipv6 { export all; };
}
protocol bgp LINK {
local {{ link["dest"]["ipv6"].ip }} as 2;
neighbor {{ link["src"]["ipv6"].ip }} as 1;
ipv6 {
import all;
export none;
};
}

View File

@ -0,0 +1,99 @@
log "bird.log" all;
router id 1;
define epoch = 1;
ipv6 table master6 sorted;
debug tables all;
debug channels all;
protocol device {
scan time 10;
}
protocol kernel kernel6 {
scan time 10;
ipv6 { export all; };
}
protocol static p200 {
ipv6 { import filter { preference = 200; accept; }; };
route 2001:db8:eee1::/48 unreachable;
route 2001:db8:eee2::/48 unreachable;
route 2001:db8:eee3::/48 unreachable;
route 2001:db8:eee4::/48 unreachable;
route 2001:db8:eee5::/48 unreachable;
route 2001:db8:eee6::/48 unreachable;
disabled;
}
protocol static p190 {
ipv6 { import filter { preference = 190; accept; }; };
route 2001:db8:eee1::/48 unreachable;
route 2001:db8:eee2::/48 unreachable;
route 2001:db8:eee3::/48 unreachable;
route 2001:db8:eee4::/48 unreachable;
route 2001:db8:eee5::/48 unreachable;
route 2001:db8:eee6::/48 unreachable;
disabled;
}
protocol static p180 {
ipv6 { import filter { preference = 180; accept; }; };
route 2001:db8:eee1::/48 unreachable;
route 2001:db8:eee2::/48 unreachable;
route 2001:db8:eee3::/48 unreachable;
route 2001:db8:eee4::/48 unreachable;
route 2001:db8:eee5::/48 unreachable;
route 2001:db8:eee6::/48 unreachable;
disabled;
}
protocol static p170 {
ipv6 { import filter { preference = 170; accept; }; };
route 2001:db8:eee1::/48 unreachable;
route 2001:db8:eee2::/48 unreachable;
route 2001:db8:eee3::/48 unreachable;
route 2001:db8:eee4::/48 unreachable;
route 2001:db8:eee5::/48 unreachable;
route 2001:db8:eee6::/48 unreachable;
disabled;
}
# We need to CHECK this:
# - adding worst to best
# - adding best to worst
# - removing (both dirs)
# - reconf
function CHECK() -> bool {
bgp_path.prepend(preference);
case epoch {
1: case preference {
170: return net ~ [ 2001:db8:eee4::/48, 2001:db8:eee5::/48 ];
180: return net ~ [ 2001:db8:eee3::/48 ];
190: return net ~ [ 2001:db8:eee2::/48, 2001:db8:eee4::/48 ];
200: return net ~ [ 2001:db8:eee1::/48, 2001:db8:eee3::/48 ];
else: return false;
}
2: case preference {
170: return net ~ [ 2001:db8:eee5::/48, 2001:db8:eee6::/48 ];
180: return net ~ [ 2001:db8:eee4::/48 ];
190: return net ~ [ 2001:db8:eee3::/48, 2001:db8:eee5::/48 ];
200: return net ~ [ 2001:db8:eee2::/48, 2001:db8:eee4::/48 ];
else: return false;
}
else: return false;
}
}
protocol bgp LINK {
local {{ link["src"]["ipv6"].ip }} as 1;
neighbor {{ link["dest"]["ipv6"].ip }} as 2;
ipv6 {
import none;
export where CHECK();
secondary;
};
}

View File

@ -0,0 +1,98 @@
#!/usr/bin/python3
import asyncio
import ipaddress
import jinja2
import os
import pathlib
import sys
sys.path.insert(0, "/home/maria/flock")
import flock.Hypervisor as Hypervisor
async def main():
h = Hypervisor.Hypervisor("bgp-secondary")
await h.prepare()
os.symlink(pathlib.Path("bgp-secondary.log").absolute(), h.basedir / "flock.log")
await h.start()
src, dest = await asyncio.gather(
h.control_socket.send_cmd_early("machine", "src", { "type": "minimalist"}),
h.control_socket.send_cmd_early("machine", "dest", { "type": "minimalist"}),
)
for q in src, dest:
q["workdir"] = pathlib.Path(q["workdir"])
link, = await asyncio.gather(
h.control_socket.send_cmd("link", "L", {
"machines": {
"src": { "name": "L" },
"dest": { "name": "L" },
},
"ipv6": "2001:db8:0:1::/64",
"ipv4": "10.0.1.0/29",
}),
)
for m in link:
for t in ("ipv4", "ipv6"):
link[m][t] = ipaddress.ip_interface(link[m][t])
print(link, src, dest)
env = jinja2.Environment()
src_conf = open("bird_src.conf", "r").read()
jt = env.from_string(src_conf)
with open(src["workdir"] / "bird.conf", "w") as f:
f.write(jt.render( link=link ))
dest_conf = open("bird_dest.conf", "r").read()
jt = env.from_string(dest_conf)
with open(dest["workdir"] / "bird.conf", "w") as f:
f.write(jt.render( link=link ))
with open(pathlib.Path.cwd() / ".." / ".." / "bird", "rb") as b:
with open(dest["workdir"] / "bird", "wb") as d:
d.write(dta := b.read())
with open(src["workdir"] / "bird", "wb") as d:
d.write(dta)
with open(pathlib.Path.cwd() / ".." / ".." / "birdc", "rb") as b:
with open(dest["workdir"] / "birdc", "wb") as d:
d.write(dta := b.read())
with open(src["workdir"] / "birdc", "wb") as d:
d.write(dta)
os.chmod(dest["workdir"] / "bird", 0o755)
os.chmod(src["workdir"] / "bird", 0o755)
os.chmod(dest["workdir"] / "birdc", 0o755)
os.chmod(src["workdir"] / "birdc", 0o755)
print(await asyncio.gather(*[
h.control_socket.send_cmd("run_in", where, "./bird", "-l")
for where in ("src", "dest")
]))
"""
print(await asyncio.gather(
h.control_socket.send_cmd("run_in", "src", "ip", "a"),
h.control_socket.send_cmd("run_in", "dest", "ip", "a"),
))
"""
await asyncio.sleep(30)
print(await asyncio.gather(*[
h.control_socket.send_cmd("run_in", where, "./birdc", "-l", "down")
for where in ("src", "dest")
]))
await asyncio.sleep(1)
await h.control_socket.send_cmd("stop", True)
assert(__name__ == "__main__")
asyncio.run(main())