Documentation ¶
Index ¶
- Variables
- func Handle(t Type, handler Handler)
- func HandleFunc(t Type, f func(ResponseWriter, *Request))
- func HandleOnce(t Type, handler Handler)
- func ListenAndServe(addr string, handler Handler) error
- func Send(c Conn, requests ...*Request) error
- type Conn
- type ConnState
- type CookieJar
- type CookieMatcher
- type CookieReader
- type CookieReaderFunc
- type Handler
- type HandlerFunc
- type Header
- type Listener
- type Matcher
- type MatcherFunc
- type MultiRoutineRunner
- type OnDemandRoutineRunner
- type Request
- type ResponseWriter
- type Runner
- type SequentialRunner
- type ServeMux
- type Server
- type Type
- type TypeMatcher
- type TypeMux
Constants ¶
This section is empty.
Variables ¶
var ( // ErrBodyTooLong is returned when actual request body exceeds the // length specified in the request header. ErrBodyTooLong = errors.New("openflow: Request body is too long") // ErrCorruptedHeader is returned when request body does not match // the length specified in a request header. ErrCorruptedHeader = errors.New("openflow: Corrupted header") )
var DefaultHandler = DiscardHandler
DefaultHandler is the Handler used for Requests that don't have a Matcher.
var DefaultMux = NewTypeMux()
DefaultMux is an instance of the TypeMux used as a default handler in the DefaultServer instance.
var DiscardHandler = HandlerFunc(func(rw ResponseWriter, r *Request) {})
DiscardHandler is a Handler instance to discard the remote OpenFlow requests.
Functions ¶
func Handle ¶
Handle registers the handler for the given message type message in the DefaultMux. The documentation for TypeMux
func HandleFunc ¶
func HandleFunc(t Type, f func(ResponseWriter, *Request))
HandleFunc registers the handler function on the given message type in the DefaultMux.
func HandleOnce ¶
HandleOnce registers a disposable handler for the given message type in the DefaultMux.
func ListenAndServe ¶
ListenAndServe listens on the given TCP address the handler. When handler set to nil, the default handler will be used.
A trivial example is:
of.HandleFunc(of.TypeEchoRequest, func(rw of.ResponseWriter, r *of.Request) { rw.Write(&of.Header{Type: of.TypeEchoReply}, nil) }) of.ListenAndServe(":6633", nil)
Types ¶
type Conn ¶
type Conn interface { // Receive receives message from input buffer Receive() (*Request, error) // Send writes message to output buffer Send(*Request) error // Close closes the connection. Any blocked Read or Write operations // will be unblocked and return errors. Close() error // Flush writes the messages from output buffer to the connection. Flush() error // LocalAddr returns the local network address. LocalAddr() net.Addr // RemoteAddr returns the remote network address. RemoteAddr() net.Addr // SetDeadline sets the read and write deadlines associated with the // connection. SetDeadline(t time.Time) error // SetReadDeadline sets the deadline for the future Receive calls. // If the deadline is reached, Receive will fail with a timeout (see // type Error) instead of blocking. SetReadDeadline(t time.Time) error // SetWriteDeadLine sets the deadline for the future Send calls. // If the deadline is reached, Send will fail with a timeout (see // type Error) instead of blocking. SetWriteDeadline(t time.Time) error }
Conn is an generic OpenFlow connection.
Multiple goroutines may invoke methods on conn simultaneously.
type ConnState ¶
type ConnState int
A ConnState represents the state of a client connection to a server. It's used by the optional Server.ConnState hook.
const ( // StateNew represents a new connection that is expected to // send a request immediately. Connections begin at this // state and the transition to either StateHandshake or // StateClosed. StateNew ConnState = iota // StateHandshake represents a connection that has initiated // OpenFlow handshake routine. After the request is handled, // the state transitions to one of: StateHandshake, StateActive, // StateIdle or StateClosed. StateHandshake // StateActive represents a connection that has read 1 or more // bytes of the request. The Server.ConnState hook for StateActive // fires before the request has been handled. StateActive // StateIdle represents a connection that has finished // handling a request and is in the keep-alive state, waiting // for a new request. Connections transition from StateIdle // to StateHandshake, StateActive or StateClosed StateIdle // StateClosed represents a closed connection. This is a // terminal state. StateClosed )
type CookieMatcher ¶
type CookieMatcher struct { Cookies uint64 // Reader is an OpenFlow message unmarshaler. CookieFilter will use // it to access the request cookie value. If the cookie matches, the // registered handler will be called to process the request. Otherwise // the request will be skipped. Reader CookieReader }
CookieMatcher provides mechanism to hook up the message handler with an opaque data. Filter is safe for concurrent use by multiple goroutines.
func NewCookieMatcher ¶
func NewCookieMatcher(j CookieJar) *CookieMatcher
NewCookieMatcher creates a new cookie matcher. The cookie value will be randomly generated using the functions from the standard library.
func (*CookieMatcher) Match ¶
func (f *CookieMatcher) Match(r *Request) bool
Match compares the cookie from the message with the given one.
Cookie of each incoming request will be compared to the given cookie jar cookie. If the request cookie matches the registered one, the given handler will be used to process the request.
type CookieReader ¶
CookieReader is the interface to read cookie jars.
CookieReader parses the body of the handling request and returns the cookie jar with containing cookies or nil when error occurs.
func CookieReaderOf ¶
func CookieReaderOf(j CookieJar) CookieReader
CookieReaderOf creates a new cookie reader instance from the cookie jar. It uses reflection to create a new examplar of the given type, so the resulting reader is safe to use in multiple go-routines.
type CookieReaderFunc ¶
The CookieReaderFunc is an adapter to allow use of ordinary functions as OpenFlow handlers. If fn is a function with the appropriate signature, CookieReaderFunc(fn) is a Reader that calls fn.
func (CookieReaderFunc) ReadCookie ¶
func (fn CookieReaderFunc) ReadCookie(r io.Reader) (CookieJar, error)
ReadCookie calls the function with the specifier reader argument.
type Handler ¶
type Handler interface {
Serve(ResponseWriter, *Request)
}
A Handler responds to an OpenFlow request.
Serve should write the reply headers and the payload to the ResponseWriter and then return. Returning signals that the request is finished.
type HandlerFunc ¶
type HandlerFunc func(ResponseWriter, *Request)
The HandlerFunc type is an adapter to allow use of ordinary functions as OpenFlow handlers.
func (HandlerFunc) Serve ¶
func (h HandlerFunc) Serve(rw ResponseWriter, r *Request)
Serve calls f(rw, r).
type Header ¶
type Header struct { // Version specifies the version of the protocol. Version uint8 // Type defines a type of the message. Type Type // Length including this Header. Length uint16 // Transaction is an transaction ID associated with this packet. // // Replies use the same id as was in the request to facilitate pairing. Transaction uint32 }
The Header is a response header. It contains the negotiated version of the OpenFlow, a type and length of the message.
type Listener ¶
type Listener interface { // Accept waits for and returns the next connection. Accept() (Conn, error) // Close closes the listener. Close() error // Addr returns the listener network address. Addr() net.Addr }
Listener is an OpenFlow network listener. Clients should typically use variables of type net.Listener instead of assuming OFP.
func NewListener ¶
NewListener creates a new instance of the OpenFlow listener from the given network listener.
This function could be used to establish the communication channel over non-TCP sockets, like Unix sockets.
type Matcher ¶
A Matcher interface is used by multiplexer to find the handler for the received request.
func MultiMatcher ¶
MultiMatcher creates a new Matcher instance that matches the request by all specified criteria.
func TransactionMatcher ¶
TransactionMatcher creates a new matcher that matches the request by the transaction identifier.
If the header has non-zero transaction identifier, it will be used to create a new matcher, otherwise a random number will be generated.
type MatcherFunc ¶
MatcherFunc type is an adapter to allow the use of ordinary functions as OpenFlow request matchers.
func (*MatcherFunc) Match ¶
func (m *MatcherFunc) Match(r *Request) bool
Match implements Matcher interface and calls fn(r).
type MultiRoutineRunner ¶
type MultiRoutineRunner struct {
// contains filtered or unexported fields
}
MultiRoutineRunner is a runner that assigns each function to one of the workers from the pool. So there is always a constant amount of goroutines.
func NewMultiRoutineRunner ¶
func NewMultiRoutineRunner(num int) *MultiRoutineRunner
NewMultiRoutineRunner creates a new instance of MultiRoutinerRunner with a specified amount of workers. Method panics when number is not positive.
func (*MultiRoutineRunner) Run ¶
func (mrr *MultiRoutineRunner) Run(fn func())
Run puts a function in the waiting queue and exists. This method returns control to the parent caller.
type OnDemandRoutineRunner ¶
type OnDemandRoutineRunner struct{}
OnDemandRoutineRunner is a runner that starts each function in a separate goroutine. This handler is useful for initial prototyping, but it is highly recommended to use runner with a fixed amount of workers in order to prevent over goroutining (see MultiRoutineRunner).
func (OnDemandRoutineRunner) Run ¶
func (OnDemandRoutineRunner) Run(fn func())
Run starts a function in a separate go-routine. This method implements Runner interface.
type Request ¶
type Request struct { // Header contains the request header fields either received by // the server or sent by the client. Header Header // Body is the request's body. For client requests a nil // body means the request has no body, such as a echo requests. // // For server requests the Request Body is always non-nil // but will return EOF immediately when no body is present. Body io.Reader // The protocol version for incoming requests. // Client requests always use OFP/1.3. Proto string ProtoMajor int // 1 ProtoMinor int // 3 Addr net.Addr // ContentLength records the length of the associated content. // Values >= 0 indicate that the given number of bytes may // be read from Body. ContentLength int64 // contains filtered or unexported fields }
A Request represents an OpenFlow request received by the server or to be sent by a client.
The field semantics differ slightly between client and server usage.
func NewRequest ¶
NewRequest returns a new Request given a type, address, and optional body.
func (*Request) ProtoAtLeast ¶
ProtoAtLeast reports whether the OpenFlow protocol used in the request is at least major.minor.
type ResponseWriter ¶
type ResponseWriter interface { // Write writes the data to the connection as part of an OpenFlow reply. Write(*Header, io.WriterTo) error }
A ResponseWriter interface is used by an OpenFlow handler to construct an OpenFlow Response.
type Runner ¶
type Runner interface {
Run(func())
}
Runner describes types used to start a function according to the defined concurrency model.
type SequentialRunner ¶
type SequentialRunner struct{}
SequentialRunner is a runner that starts each function one by one. New function does not start execution until the previous one is done.
This runner is useful for debugging purposes.
func (SequentialRunner) Run ¶
func (SequentialRunner) Run(fn func())
Run starts a function as is. This method implements Runner interface.
type ServeMux ¶
type ServeMux struct {
// contains filtered or unexported fields
}
ServeMux is an OpenFlow request multiplexer.
func (*ServeMux) HandleFunc ¶
func (mux *ServeMux) HandleFunc(m Matcher, h HandlerFunc)
HandleFunc registers handler function for the given pattern.
func (*ServeMux) HandleOnce ¶
HandleOnce registers disposable handler for the given pattern.
It is not guaranteed that handler will process the first message exemplar of the matching message.
func (*ServeMux) Serve ¶
func (mux *ServeMux) Serve(rw ResponseWriter, r *Request)
Serve implements Handler internface. It processing the request and writes back the response.
type Server ¶
type Server struct { // Addr is an address to listen on. Addr string // HandlerRunner defines concurrency model of handling requests from // the switch within a single connection. // // By default OnDemandRoutineRunner is used. HandlerRunner Runner // Handler to invoke on the incoming requests. Handler Handler // Maximum duration before timing out the read of the request. ReadTimeout time.Duration // Maximum duration before timing out the write of the response. WriteTimeout time.Duration // ConnRunner defines concurrency model of processing client connections. // // By default each accepted connection is handled in a standalone // goroutine. Such approach could result in a consuming all CPU and // Memory resourses of the computer, therefore it is higly recommended // to server connections only on a fixed amount of workers (see // MultiRoutineRunner). ConnRunner Runner // ConnState specifies an optional callback function that is called // when a client connection changes state. ConnState func(Conn, ConnState) // MaxConns defines the maximum number of client connections server // handles, the rest will be explicitly closed. Zero means no limit. MaxConns int // contains filtered or unexported fields }
A Server defines parameters for running OpenFlow server.
func (*Server) ListenAndServe ¶
ListenAndServe listens on the network address and then calls Server to handle requests on the incoming connections.
type Type ¶
type Type uint8
Type is an OpenFlow message type.
const ( // TypeHello is used by either controller or switch during connection // setup. It is used for version negotiation. When the connection // is established, each side must immediately send a Hello message // with the version field set to the highest version supported by // the sender. If the version negotiation fails, an Error message // is sent with type HelloFailed and code Incompatible. TypeHello Type = iota // TypeError can be sent by either the switch or the controller and // indicates the failure of an operation. The simplest failure pertain // to malformed messages or failed version negotiation, while more // complex scenarios desbie some failure in state change at the switch. TypeError // TypeEchoRequest is used to exchange information about latency, // bandwidth and liveness. Echo request timeout indicates disconnection. TypeEchoRequest // TypeEchoReply is used to exchange information about latency, // bandwidth and liveness. Echo reply is sent as a response to Echo // request. TypeEchoReply // TypeExperiment is a mechanism for proprietary messages within the // protocol. TypeExperiment // TypeFeaturesRequest is used when a transport channel (TCP, SCTP, // TLS) is established between the switch and controller, the first // activity is feature determination. The controller will send a // feature request to the switch over the transport channel. TypeFeaturesRequest // TypeFeaturesReply is the switch's reply to the controller // enumerating its abilities. TypeFeaturesReply // TypeGetConfigRequest sequence is used to query and set the // fragmentation handling properties of the packet processing pipeline. TypeGetConfigRequest // TypeGetConfigReply is the switch's reply to the controller // that acknowledges configuration requests. TypeGetConfigReply // TypeSetConfig is used by the controller to alter the switch's // configuration. This message is unacknowledged. TypeSetConfig // TypePacketIn message is a way for the switch to send a captured // packet to the controller. TypePacketIn // TypeFlowRemoved is sent to the controller by the switch when a // flow entry in a flow table is removed. It happens when a timeout // occurs, either due to inactivity or hard timeout. An idle timeout // happens when no packets are matched in a period of time. A hard // timeout happens when a certain period of time elapses, regardless // of the number of matching packets. Whether the switch sends a // TypeFlowRemoved message after a timeout is specified by the // TypeFlowMod. Flow entry removal with a TypeFlowMod message from // the controller can also lead to a TypeFlowRemoved message. TypeFlowRemoved // TypePortStatus messages are asynchronous events sent from the // switch to the controller indicating a change of status for the // indicated port. TypePortStatus // TypePacketOut is used by the controller to inject packets into the // data plane of a particular switch. Such message can either carry a // raw packet to inject into the switch, or indicate a local buffer // on the switch containing a raw packet to release. Packets injected // into the data plane of a switch using this method are not treated // the same as packets that arrive on standard ports. The packet jumps // to the action set application stage in the standard packet processing // pipeline. If the action set indicates table processing is necessary // then the input port id is used as the arrival port of the raw packet. TypePacketOut // TypeFlowMod is one of the main messages, it allows the controller // to modify the state of switch. TypeFlowMod // TypeGroupMod is used by controller to modify group tables. TypeGroupMod // TypePortMod is used by the controller to modify the state of port. TypePortMod // TypeTableMod is used to determine a packet's fate when it misses // in the table. It can be forwarded to the controller, dropped, or // sent to the next table. TypeTableMod // TypeMultipartRequest is used by the controller to request the // state of the datapath. TypeMultipartRequest // TypeMultipartReply are the replies from the switch to controller // on TypeMultipartRequest messages. TypeMultipartReply // TypeBarrierRequest can be used by the controller to set a // synchronization point, ensuring that all previous state messages // are completed before the barrier response is sent back to the // controller. TypeBarrierRequest // TypeBarrierReply is a response from the switch to controller // on TypeBarrierRequest messages. TypeBarrierReply // TypeQueueGetConfigRequest can be used by the controller to // query the state of queues associated with various ports on switch. TypeQueueGetConfigRequest // TypeQueueGetConfigReply is a response from the switch to controller // on TypeQueueGetConfigReply messages. TypeQueueGetConfigReply // TypeRoleRequest is the message used by the controller to // modify its role among multiple controllers on a switch. TypeRoleRequest // TypeRoleReply is a response from the switch to controller on // TypeRoleRequest. TypeRoleReply // TypeGetAsyncRequest is used by the controller to request the switch // which asynchronous events are enabled on the switch for the // communication channel. TypeGetAsyncRequest // TypeGetAsyncReply is used by the switch as response to controller // on TypeAsyncRequest messages. TypeGetAsyncReply // TypeSetAsync is used by the controller to set which asynchronous // messages it should send, as well as to query the switch for which // asynchronous messages it will send. TypeSetAsync // TypeMeterMod used by the controller to modify the meter. TypeMeterMod )
type TypeMatcher ¶
type TypeMatcher Type
TypeMatcher used to match requests by their types.
func (TypeMatcher) Match ¶
func (t TypeMatcher) Match(r *Request) bool
Match implements Matcher interface and matches the request by the type.
type TypeMux ¶
type TypeMux struct {
// contains filtered or unexported fields
}
TypeMux is an OpenFlow request multiplexer. It matches the type of the OpenFlow message against a list of registered handlers and calls the marching handler.
func (*TypeMux) HandleFunc ¶
func (mux *TypeMux) HandleFunc(t Type, f HandlerFunc)
HandleFunc registers handler function for the given message type.
func (*TypeMux) HandleOnce ¶
HandleOnce registers a disposable handler for the given message type.
func (*TypeMux) Serve ¶
func (mux *TypeMux) Serve(rw ResponseWriter, r *Request)
Serve implements Handler internface. It processing the request and writes back the response.