package frenetic
The Frenetic Programming Language and Runtime System
Install
Dune Dependency
Authors
Maintainers
Sources
5.0.5.tar.gz
md5=baf754df13a759c32f2c86a1b6f328da
sha512=80140900e7009ccab14b25e244fe7edab87d858676f8a4b3799b4fea16825013cf68363fe5faec71dd54ba825bb4ea2f812c2c666390948ab217ffa75d9cbd29
doc/src/frenetic.netkat/Portless_Compiler.ml.html
Source file Portless_Compiler.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
open Core open Syntax module Network = Frenetic_kernel.Network module Net = Network.Net module Topology = Net.Topology type direction = Incoming | Outgoing type topo = (abstract_location, Topology.vertex) Hashtbl.t * Topology.t let connected_switches ~loc ~direction ~topo = let (name_to_vertex_table, network) = topo in let vertex = Hashtbl.find name_to_vertex_table loc in match vertex with | None -> failwith "no such location" | Some loc -> let neighbors = Topology.neighbors network loc in Topology.VertexSet.fold neighbors ~init:[] ~f:(fun acc other -> let node = Topology.vertex_to_label network other in if Poly.(Network.Node.device node = Switch) then let edges = match direction with | Incoming -> Topology.find_all_edges network other loc | Outgoing -> Topology.find_all_edges network loc other in Topology.EdgeSet.fold edges ~init:acc ~f:(fun acc edge -> let v, port = match direction with | Incoming -> Topology.edge_src edge | Outgoing -> Topology.edge_dst edge in (Network.Node.id (Topology.vertex_to_label network other), port) :: acc) else acc) let abs_loc_to_switch (topo: topo) loc = let (name_to_vertex_table, network) = topo in let vertex = Hashtbl.find name_to_vertex_table loc in match vertex with | Some v -> let node = (Topology.vertex_to_label network v) in if Poly.(Network.Node.device node = Switch) then Network.Node.id node else failwith "the location is not a switch" | None -> failwith "no such location" let is_loc_host (topo: topo) loc = let (name_to_vertex_table, network) = topo in let vertex = Hashtbl.find name_to_vertex_table loc in match vertex with | Some v -> Poly.(Network.Node.device (Topology.vertex_to_label network v) = Host) | None -> failwith "no such location" let portify_pred pred (topo: topo) = let rec portify_pred' pred (k: pred -> pred) = match pred with | True -> k True | False -> k False | And (pred1, pred2) -> portify_pred' pred1 (fun x -> portify_pred' pred2 (fun y -> k (And (x, y)))) | Or (pred1, pred2) -> portify_pred' pred1 (fun x -> portify_pred' pred2 (fun y -> k (Or (x, y)))) | Neg pred -> portify_pred' pred (fun x -> k (Neg x)) | Test header -> match header with | AbstractLoc loc -> k (Test (Switch (abs_loc_to_switch topo loc))) | From loc -> let from_list = connected_switches loc Incoming topo in List.fold from_list ~init:(False) ~f:(fun acc (sw, pt) -> k (Or (acc, And ( (Test (Switch sw)), (Test (Location (Physical pt))))))) | Switch _ | Location _ -> failwith "cannot specify switch and port for portless policies" | x -> k (Test x) in portify_pred' pred (fun x -> x) let portify_pol_fdd (portless_pol_fdd: Local_compiler.t) (topo: topo): policy = let rec portify_pol' portless_pol k = match portless_pol with | Union (pol1, pol2) -> portify_pol' pol1 (fun x -> portify_pol' pol2 (fun y -> k (Union (x, y)))) | Seq (pol1, pol2) -> portify_pol' pol1 (fun x -> portify_pol' pol2 (fun y -> k (Seq (x, y)))) | Star pol -> portify_pol' pol (fun x -> k (Star x)) | Filter pred -> k (Filter (portify_pred pred topo)) | Let meta -> portify_pol' meta.body (fun x -> k (Let {meta with body = x})) | Dup -> k Dup | Link _ | VLink _ -> failwith "links not supported for portless policies" | Mod header -> match header with | AbstractLoc loc -> let sw_port_list = connected_switches loc Outgoing topo in k (List.fold sw_port_list ~init:(if is_loc_host topo loc then drop else Filter (Test (Switch (abs_loc_to_switch topo loc)))) ~f:(fun acc (sw, mod_pt) -> let portful_test = Test (Switch sw) in let portful_mod = Mod (Location (Physical mod_pt)) in Union (acc, Seq (Filter portful_test, portful_mod)))) | From loc -> k id | Switch _ | Location _ -> failwith "cannot specify switch and port for portless policies" | x -> k (Mod x) in let portless_pol = Local_compiler.to_local_pol portless_pol_fdd in portify_pol' portless_pol (fun x -> x) let make_topo (network: Topology.t): topo = let name_to_vertex_table = String.Table.create () in Topology.iter_vertexes (fun vertex -> let vertex_name = (Network.Node.name (Topology.vertex_to_label network vertex)) in let _ = Hashtbl.add name_to_vertex_table vertex_name vertex in ()) network; (name_to_vertex_table, network) let compile portless_pol (network: Topology.t) = let topo = make_topo network in let portless_pol_fdd = Local_compiler.compile portless_pol in portify_pol_fdd portless_pol_fdd topo
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>