summaryrefslogtreecommitdiff
path: root/6/bgp.pl
diff options
context:
space:
mode:
Diffstat (limited to '6/bgp.pl')
-rw-r--r--6/bgp.pl99
1 files changed, 99 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}).