diff options
Diffstat (limited to '6/bgp.pl')
-rw-r--r-- | 6/bgp.pl | 99 |
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}). |