Writing a switch's rules by hand
The command ovs-ofctl adds, lists and removes the flows in an Open vSwitch switch. Writing a flow by hand shows exactly what a controller does for you automatically.
You will turn a rule written in plain words into a flow, and test it before any real packet is sent.
By the end of this lesson
Note
I can turn a rule in words into a flow and test it with a trace.
Key words
| Word | What it means | Example |
|---|---|---|
| Policy | the rules a network must follow, in plain words | |
| ovs-ofctl | the command that manages flows in the switch | |
| add-flow | the ovs-ofctl word that adds one flow | |
| Default deny | drop everything that no rule allows | |
| Output action | send the packet out of one port | actions=output:3 |
The cells students fill in are left blank in this preview.
One rule in words becomes one flow
A school writes its policy in words. The staff computer on port 1 may reach the file server on port 3, and back. Nobody may use telnet. Everything else is dropped.
Each rule becomes one flow. Give the exceptions a high priority and the general rule a low one, so the exceptions are checked first.
Worked example: a policy turned into flows
| Rule in words | Flow |
|---|---|
| Nobody may use telnet | priority=100,tcp,tp_dst=23,actions=drop |
| Port 1 may send to port 3 | priority=10,in_port=1,actions=output:3 |
| Port 3 may send to port 1 | priority=10,in_port=3,actions=output:1 |
| Drop everything else | priority=0,actions=drop |
The cells students fill in are left blank in this preview.
A flow works in one direction only
A conversation has two directions. A request goes from port 1 to port 3, and the answer comes back from port 3.
A flow for in_port=1 says nothing about packets that come in on port 3. Without a flow for the way back, the answer meets the default and is dropped, and the conversation fails.
A common mistake
Warning
Many people think one flow covers a conversation in both directions. It covers only the packets that match it. A flow for traffic coming in on port 1 does nothing for the replies coming in on port 3. Write one flow for each direction.
Test a policy in your lab
You will type this policy into the switch by hand, but leave out the way back from port 3. Then you will see the ping fail, add the missing flow and see it work.
Flows typed by hand are lost when the lab is rebuilt, so this does not change your own work. The lab's ports are 1 for h1, 2 for h2 and 3 for h3.
Rebuild the lab with no controller
sudo sdnlab flowsShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Empty the flow table
sudo ovs-ofctl -O OpenFlow13 del-flows br0Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Type three flows by hand
printf 'priority=0,actions=drop\npriority=100,tcp,tp_dst=23,actions=drop\npriority=10,in_port=1,actions=output:3\n' | sudo ovs-ofctl -O OpenFlow13 add-flows br0 -Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
List the flows
sudo ovs-ofctl -O OpenFlow13 dump-flows br0 --no-statsShown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Ping h3 from h1
sudo ip netns exec h1 ping -c 1 -W 1 -q 10.0.0.3 | grep -o "100% packet loss"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
The request arrived, the answer did not
The ping lost every packet. Port 1 may send to port 3, so the request arrived. The answer came back in on port 3, and no flow covers that, so it met the drop at priority 0. Now add the missing direction.
Add the flow for the way back
sudo ovs-ofctl -O OpenFlow13 add-flow br0 priority=10,in_port=3,actions=output:1Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Ping h3 from h1 again
sudo ip netns exec h1 ping -c 1 -W 1 -q 10.0.0.3 | grep -o ", 0% packet loss"Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
Trace telnet in on port 3
sudo ovs-appctl ofproto/trace br0 in_port=3,tcp,tp_dst=23 | grep -A1 "^ 0\."Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.
The policy works and the exception holds
The second ping lost none. The flows cover everything from the port, so the ARP packets that start a ping got through as well.
The trace shows the telnet rule at priority 100 beating the allow rule at priority 10, even from port 3. Your lab's own flow file uses these same lines, one per line. Run sudo sdnlab flows to put the lab back.