package frenetic

  1. Overview
  2. Docs
Legend:
Library
Module
Module type
Parameter
Class
Class type

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 Identifier Types

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 switchId = int64
val equal_switchId : switchId -> switchId -> Ppx_deriving_runtime.bool
val sexp_of_switchId : switchId -> Ppx_sexp_conv_lib.Sexp.t
val switchId_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> switchId
val compare_switchId : switchId -> switchId -> int
type portId = int32
val equal_portId : portId -> portId -> Ppx_deriving_runtime.bool
val sexp_of_portId : portId -> Ppx_sexp_conv_lib.Sexp.t
val portId_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> portId
val compare_portId : portId -> portId -> int
type queueId = int32
val equal_queueId : queueId -> queueId -> Ppx_deriving_runtime.bool
val sexp_of_queueId : queueId -> Ppx_sexp_conv_lib.Sexp.t
val queueId_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> queueId
val compare_queueId : queueId -> queueId -> int
type bufferId = int32
val equal_bufferId : bufferId -> bufferId -> Ppx_deriving_runtime.bool
val sexp_of_bufferId : bufferId -> Ppx_sexp_conv_lib.Sexp.t
val bufferId_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> bufferId
val compare_bufferId : bufferId -> bufferId -> int
exception Unsupported of string

Packet Types

type payload =
  1. | Buffered of bufferId * Cstruct.t
    (*

    Buffered (id, buf) is a packet buffered on a switch

    *)
  2. | NotBuffered of Cstruct.t

Packet payloads

val sexp_of_payload : payload -> Ppx_sexp_conv_lib.Sexp.t
val payload_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> payload
val payload_bytes : payload -> Cstruct.t

payload_bytes payload returns the bytes for the given payload

type packetInReason =
  1. | NoMatch
  2. | ExplicitSend
val sexp_of_packetInReason : packetInReason -> Ppx_sexp_conv_lib.Sexp.t
val packetInReason_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> packetInReason

Switch Configuaration

type switchFeatures = {
  1. switch_id : switchId;
  2. switch_ports : portId list;
}

A simplification of the _switch features_ message from OpenFlow

val sexp_of_switchFeatures : switchFeatures -> Ppx_sexp_conv_lib.Sexp.t
val switchFeatures_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> switchFeatures

Packet Forwarding

module Pattern : sig ... end
val sexp_of_modify : modify -> Ppx_sexp_conv_lib.Sexp.t
val modify_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> modify
type pseudoport =
  1. | Physical of portId
  2. | InPort
  3. | Table
  4. | Normal
  5. | Flood
  6. | All
  7. | Controller of int
  8. | Local
val sexp_of_pseudoport : pseudoport -> Ppx_sexp_conv_lib.Sexp.t
val pseudoport_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> pseudoport
type groupId = int32
val sexp_of_groupId : groupId -> Ppx_sexp_conv_lib.Sexp.t
val groupId_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> groupId
type action =
  1. | Output of pseudoport
  2. | Enqueue of portId * queueId
  3. | Modify of modify
  4. | FastFail of groupId
val sexp_of_action : action -> Ppx_sexp_conv_lib.Sexp.t
val action_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> action
type seq = action list
val sexp_of_seq : seq -> Ppx_sexp_conv_lib.Sexp.t
val seq_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> seq
type par = seq list
val sexp_of_par : par -> Ppx_sexp_conv_lib.Sexp.t
val par_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> par
type group = par list
val sexp_of_group : group -> Ppx_sexp_conv_lib.Sexp.t
val group_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> group
type timeout =
  1. | Permanent
    (*

    No timeout

    *)
  2. | ExpiresAfter of Frenetic_kernel.Packet.int16
    (*

    Time out after n seconds

    *)
val sexp_of_timeout : timeout -> Ppx_sexp_conv_lib.Sexp.t
val timeout_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> timeout
type flow = {
  1. pattern : Pattern.t;
  2. action : group;
  3. cookie : int64;
  4. idle_timeout : timeout;
  5. hard_timeout : timeout;
}
val sexp_of_flow : flow -> Ppx_sexp_conv_lib.Sexp.t
val flow_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> flow
type flowTable = flow list

Priorities are implicit

val sexp_of_flowTable : flowTable -> Ppx_sexp_conv_lib.Sexp.t
val flowTable_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> flowTable
type flowStats = {
  1. flow_table_id : int64;
  2. flow_pattern : Pattern.t;
  3. flow_actions : action list;
  4. flow_duration_sec : int64;
  5. flow_duration_nsec : int64;
  6. flow_priority : int64;
  7. flow_idle_timeout : int64;
  8. flow_hard_timeout : int64;
  9. flow_packet_count : int64;
  10. flow_byte_count : int64;
}

The body of a reply to an individual flow statistics request

val sexp_of_flowStats : flowStats -> Ppx_sexp_conv_lib.Sexp.t
val flowStats_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> flowStats
type portStats = {
  1. port_no : int64;
  2. port_rx_packets : int64;
  3. port_tx_packets : int64;
  4. port_rx_bytes : int64;
  5. port_tx_bytes : int64;
  6. port_rx_dropped : int64;
  7. port_tx_dropped : int64;
  8. port_rx_errors : int64;
  9. port_tx_errors : int64;
  10. port_rx_frame_err : int64;
  11. port_rx_over_err : int64;
  12. port_rx_crc_err : int64;
  13. port_collisions : int64;
}
val sexp_of_portStats : portStats -> Ppx_sexp_conv_lib.Sexp.t
val portStats_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> portStats
type event =
  1. | SwitchUp of switchId * portId list
  2. | SwitchDown of switchId
  3. | PortUp of switchId * portId
  4. | PortDown of switchId * portId
  5. | PacketIn of string * switchId * portId * payload * int * packetInReason
  6. | PortStats of switchId * portStats
  7. | FlowStats of switchId * flowStats
type pktOut = payload * portId option * action list
val sexp_of_pktOut : pktOut -> Ppx_sexp_conv_lib.Sexp.t
val pktOut_of_sexp : Ppx_sexp_conv_lib.Sexp.t -> pktOut
val format_list : 'a list -> to_string:('a -> string) -> string
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 To0x01 : sig ... end
module From0x01 : sig ... end