A uniform interface to OpenFlow 1.0 and 1.3.
A high-level language, such as Frenetic, should support OpenFlow 1.0 and also exploit OpenFlow 1.3 features when possible. For example, when two Frenetic actions are composed in parallel, they logically work on two copies of a packet. Certain kinds of parallel composition cannot be realized in OpenFlow 1.0, but they are trivial to implement with group tables in OpenFlow 1.3.
Similarly, OpenFlow 1.3 can implement failover efficiently using fast- failover groups. But, in OpenFlow 1.0, we have to incur a round-trip to the controller.
Instead of creating two different versions of the Frenetic compiler, we here define a high-level action data type. When targeting OpenFlow 1.0, actions translates to 1.0 action sequences and controller round-trips if needed. When targeting OpenFlow 1.3, action also builds group tables to realize actions efficiently. This requires a global analysis of all the actions in a flow table. Therefore, Frenetic needs to supply the entire flow table at once and cannot add and remove flow table entries individually
OpenFlow requires identifiers for switches, ports, transaction numbers, etc. The representation of these identifiers varies across different versions of OpenFlow, which is why they are abstract.
type payload
=
| Buffered of bufferId * Cstruct.t | (** |
| NotBuffered of Cstruct.t |
Packet payloads
val payload_bytes : payload ‑> Cstruct.t
payload_bytes payload
returns the bytes for the given payload
include sig ... end
val packetInReason_of_sexp : Ppx_sexp_conv_lib.Sexp.t ‑> packetInReason
val sexp_of_packetInReason : packetInReason ‑> Ppx_sexp_conv_lib.Sexp.t
include sig ... end
val switchFeatures_of_sexp : Ppx_sexp_conv_lib.Sexp.t ‑> switchFeatures
val sexp_of_switchFeatures : switchFeatures ‑> Ppx_sexp_conv_lib.Sexp.t
module Pattern : sig ... end
type modify
=
| SetEthSrc of Packet.dlAddr |
| SetEthDst of Packet.dlAddr |
| SetVlan of Packet.dlVlan |
| SetVlanPcp of Packet.dlVlanPcp |
| SetEthTyp of Packet.dlTyp |
| SetIPProto of Packet.nwProto |
| SetIP4Src of Packet.nwAddr |
| SetIP4Dst of Packet.nwAddr |
| SetTCPSrcPort of Packet.tpPort |
| SetTCPDstPort of Packet.tpPort |
include sig ... end
val pseudoport_of_sexp : Ppx_sexp_conv_lib.Sexp.t ‑> pseudoport
val sexp_of_pseudoport : pseudoport ‑> Ppx_sexp_conv_lib.Sexp.t
type action
=
| Output of pseudoport |
| Enqueue of portId * queueId |
| Modify of modify |
| FastFail of groupId |
type timeout
=
| Permanent | (** No timeout *) |
| ExpiresAfter of Packet.int16 | (** Time out after |
type flowStats
=
{
flow_table_id : int64; |
flow_pattern : Pattern.t; |
flow_actions : action list; |
flow_duration_sec : int64; |
flow_duration_nsec : int64; |
flow_priority : int64; |
flow_idle_timeout : int64; |
flow_hard_timeout : int64; |
flow_packet_count : int64; |
flow_byte_count : int64; |
}
The body of a reply to an individual flow statistics request
type portStats
=
{
}
val format_action : Format.formatter ‑> action ‑> unit
val format_seq : Format.formatter ‑> seq ‑> unit
val format_par : Format.formatter ‑> par ‑> unit
val format_group : Format.formatter ‑> group ‑> unit
val format_flow : Format.formatter ‑> flow ‑> unit
val format_flowTable : Format.formatter ‑> flowTable ‑> unit
val string_of_action : action ‑> string
val string_of_seq : seq ‑> string
val string_of_par : par ‑> string
val string_of_flow : flow ‑> string
val string_of_group : group ‑> string
val string_of_flowTable : ?label:string ‑> flowTable ‑> string
val string_of_event : event ‑> string
module OF10 = Frenetic_kernel.OpenFlow0x01
module To0x01 : sig ... end
module From0x01 : sig ... end