OpenFlow’s primary purpose is to allow a central controller to dictate the forwarding behavior of network devices, effectively removing distributed intelligence from the switches themselves.
Let’s see it in action. Imagine a simple setup: an OpenFlow-enabled switch and an OpenFlow controller (like ONOS or ODL). When a packet arrives at the switch, it checks its flow table. If there’s a matching entry, the switch performs the specified action (e.g., forward to port 2, drop, modify header). If there’s no match, the packet is typically sent to the controller for instructions. The controller then decides what to do with the packet and programs the switch’s flow table accordingly.
Consider a basic packet forwarding scenario. A packet arrives at switch s1 on port 1 destined for IP address 192.168.1.10.
// Controller sends this to s1
{
"type": "flow_mod",
"command": "add",
"match": {
"in_port": 1,
"ipv4_dst": "192.168.1.10"
},
"actions": [
{"type": "output", "port": 2}
]
}
This JSON represents an OpenFlow message. The controller is instructing switch s1 to add a new flow rule. The match criteria specify that this rule applies to packets arriving on in_port 1 with a destination IP address of 192.168.1.10. The actions dictate that matching packets should be sent out on port 2. Once this flow_mod message is processed by s1, any subsequent packets matching this criteria will be forwarded directly without consulting the controller again.
The problem OpenFlow solves is the rigidity of traditional networking. In a conventional network, each switch independently decides how to forward traffic based on its local routing tables. This makes it difficult to implement dynamic network policies, manage traffic engineering, or deploy new network services quickly. OpenFlow centralizes this decision-making process. The controller has a global view of the network and can program the forwarding behavior of all connected switches. This enables a wide range of SDN applications, from sophisticated traffic load balancing to network virtualization and security policy enforcement.
The core components of the OpenFlow protocol are:
- Messages: There are three types of messages:
- Controller-to-Switch: Commands from the controller to the switch (e.g.,
flow_modto add/remove flow rules,packet_outto send packets to specific ports). - Asynchronous: Messages from the switch to the controller that are not in response to a direct request (e.g.,
packet_inwhen a packet arrives with no matching flow rule,port_statuswhen a port state changes). - Symmetric: Messages that can be sent by either the controller or the switch (e.g.,
hellofor connection establishment,echo_request/echo_replyfor keepalives).
- Controller-to-Switch: Commands from the controller to the switch (e.g.,
- Flow Tables: These are the heart of an OpenFlow switch. Each table contains a set of flow entries.
- Flow Entries: Each flow entry consists of:
- Match Fields: Criteria that a packet header must meet (e.g., source/destination IP, VLAN ID, input port).
- Instructions: What to do with a matching packet (e.g., send to a specific port, modify headers, drop, send to controller).
- Priority: Determines which flow entry is used if a packet matches multiple entries. Higher priority wins.
- Counters: Track statistics for matching packets.
- Timeouts: How long the flow entry should remain active (idle timeout and hard timeout).
The packet_in message is crucial for learning network topology and for the controller to make forwarding decisions. When a switch receives a packet and has no matching flow entry in its tables, it sends a packet_in message to the controller. This message contains the packet data itself (or a portion of it) and the in_port where it arrived. The controller then analyzes this information. If it’s the first time seeing this packet’s destination, it might use a learning algorithm to discover the destination’s location. It then constructs a flow_mod message to program the switch (and potentially other switches) with the appropriate forwarding rule, and often a packet_out message to send the original packet on its way.
When a switch receives a packet_out message from the controller, it means the controller has decided how to handle a specific packet and is instructing the switch to send it out. This is commonly used when the controller needs to send a packet to a specific destination port, or when it’s responding to a packet_in and wants the original packet to be sent.
The primary mechanism for ensuring a robust connection between controller and switch is the echo_request and echo_reply messages. The controller periodically sends an echo_request to the switch, and the switch must respond with an echo_reply. If the controller doesn’t receive an echo_reply within a certain timeout period, it assumes the connection is down and may attempt to re-establish it or mark the switch as unreachable. This is vital for maintaining control over the network.
The OpenFlow protocol provides a standardized way for controllers to interact with switches, abstracting away vendor-specific hardware details. This standardization allows for interoperability between different vendors’ controllers and switches, fostering a more open and flexible networking ecosystem.
The concept of "tables" within an OpenFlow switch is more granular than just one big list of rules; you can have multiple tables, and instructions can specify moving a packet from one table to the next. This allows for complex, multi-stage packet processing pipelines, where different sets of rules can be applied sequentially.