diff options
Diffstat (limited to '6')
-rw-r--r-- | 6/bgp.pl | 99 | ||||
-rw-r--r-- | 6/hosts.pl | 51 | ||||
-rw-r--r-- | 6/main.pl | 16 |
3 files changed, 166 insertions, 0 deletions
diff --git a/6/bgp.pl b/6/bgp.pl new file mode 100644 index 0000000..f5dd70a --- /dev/null +++ b/6/bgp.pl @@ -0,0 +1,99 @@ +% vim set ft=prolog + +:- module(bgp, [ + warning/1, + neighbor/2, + bgp_config/2, + bird_config/1, + remote_network/2, + remote_networks/2]). +:- use_module(hosts, [ + host/1, + host_config/2, + router_link/3, + attached_network/2]). + +:- discontiguous bgp:to_dict/2. + +%host(H) :- router_link(H, _, _). +%host(H) :- router_link(_, H, _). +% host(H). + +router(R) :- host(R), hosts:host_config(R, _). +routers(Routers) :- setof(router(R), router(R), Routers). + +to_dict(router(R), Dict) :- + bgp:neighbors(R, Neighbors), + maplist(bgp:to_dict(), Neighbors, NeighborDicts), + Dict = _{ + host: R, + neighbors: NeighborDicts}. + +neighbor(H, R) :- + router(H), router(R), + router_link(H, _, R), + router_link(R, _, H). + +warning(Msg) :- + host(H), host(R), + router_link(H, _, R), + \+ router_link(R, _, H), + format(string(Msg), "Missing router_link from ~w to ~w", [R, H]). + +neighbors(H, Cs) :- findall(neighbor(H, Name), neighbor(H, Name), Cs). + +bgp_config(H, Connections) :- neighbor(H, Connections). +% bgp_config(H)? + +bird_protocol_bgp(Router, Neighbor, Address, AllowedNetworks) :- + router_link(Router, _, Neighbor), + router_link(Neighbor, Address, Router), + AllowedNetworks = []. + +% edge(a, b). edge(b, c). edge(c, d). edge(d, a). +% path(X, Y) :- edge(X, Y). +% path(X, Y) :- edge(X, Z), path(Z, Y). + +attached_networks(Router, Ns) :- + findall(N, attached_network(Router, N), Ns). + +remote_network(Router, N) :- + router_link(Router, _, Remote), + attached_network(Remote, N). + +remote_networks(Router, Ns) :- + router_link(Router, _, Remote), + attached_networks(Remote, Ns). + +% doesn't recurse +% available_networks(R, Ns) :- +% attached_networks(R, Attached), +% setof(N, remote_network(R, N), Remote), +% union(Attached, Remote, Xs), + +router_path(X, Y) :- router_path(X, Y, []). +router_path(X, Y, _) :- router_link(X, _, Y). +router_path(X, Y, V) :- \+ member(X, V), router_link(X, _, Z), router_path(Z, Y, [X|V]). + +to_yaml(neighbor(H, Remote), Dict) :- Dict = yaml(router(H), remote(Remote)). +to_json(neighbor(H, Remote), Dict) :- Dict = json(router(H), remote(Remote)). +to_dict(neighbor(_, Remote), Dict) :- host_config(Remote, RC), + Dict = neighbor{ + neighbor:_{ + name: Remote, + hostname: RC.ip + } +}. + +routers_entry(router(R), Dict) :- + D = to_dict(router(R)), + pairs_keys_values(Data, [R], [D]), + dict_create(Dict, _, Data). + +bird_config(Dict) :- + bgp:routers(Routers), + maplist(to_dict(), Routers, RouterDicts), +% maplist(routers_entry(), Routers, RouterDicts), + Dict = _{routers:RouterDicts}. +% findall(neighbor(H, R), (host(H), host(R), neighbor(H, R)), Routers), +% yaml_write(current_output, _{neighbors:BgpConnectionDicts}). diff --git a/6/hosts.pl b/6/hosts.pl new file mode 100644 index 0000000..090a172 --- /dev/null +++ b/6/hosts.pl @@ -0,0 +1,51 @@ +% vim set ft=prolog + +:- module(hosts, [ + host/1, + host_config/2, + attached_network/2, + router_link/3]). + +host(conflatorio). +host(hash). +host(knot). +host(kv24ix). +host(lhn2ix). + +host_config(knot, Config) :- Config = _{ + ip: "fdf3:aad9:a885:0b3a::1" + }. + +host_config(hash, Config) :- Config = _{ + ip: "fdf3:aad9:a885:0b3a::13" + }. + +host_config(lhn2ix, Config) :- Config = _{ + ip: "fdf3:aad9:a885:0b3a::15" + }. + +host_config(kv24ix, Config) :- Config = _{ + ip: "fdf3:aad9:a885:0b3a::16" + }. + +% (router, router_ip, remote) +router_link(knot, "1::1", hash). +router_link(knot, "1::8", lhn2ix). +router_link(knot, "1::7", kv24ix). +router_link(hash, "1::2", knot). +router_link(hash, "1::10", kv24ix). +router_link(hash, "1::3", lhn2ix). +router_link(kv24ix, "1::6", knot). +router_link(kv24ix, "1::5", hash). +router_link(lhn2ix, "1::9", hash). +router_link(lhn2ix, "1::4", knot). +router_link(conflatorio, "1::11", lhn2ix). +router_link(lhn2ix, "1::12", conflatorio). + +% network(R, address, range) +attached_network(conflatorio, ipv6_net("1:78e1::", 64)). +attached_network(hash, ipv6_net("1:e5b0::", 64)). +attached_network(knot, ipv6_net("1:f11b::", 64)). +attached_network(lhn2ix, ipv6_net("1:dbe1::", 64)). +attached_network(lhn2ix, ipv6_net("1:ab69::", 64)). +attached_network(kv42ix, ipv6_net("1:cd02::", 64)). diff --git a/6/main.pl b/6/main.pl new file mode 100644 index 0000000..cd9f807 --- /dev/null +++ b/6/main.pl @@ -0,0 +1,16 @@ +:- use_module(bgp). +% :- use_module(tnet). + +% H=knot, +% bgp:bgp_connections(H, BgpConnections), +% maplist(bgp:to_dict(), BgpConnections, BgpConnectionDicts), +% yaml_write(current_output, _{bgp_connections:BgpConnectionDicts}). + +warnings :- + bgp:warning(Ws), + writeln("Warnings: ~w", [length(Ws)]). + +main :- + bgp:bird_config(BirdDict), + yaml_write(current_output, BirdDict), + true. |