Reputation: 440
I'm trying to add a flow entry to a switch using POX controller, my code is:
fm = of.ofp_flow_mod()
fm.match.in_port = 1
fm.priority = 33001
fm.match.dl_type = 0x800
fm.match.nw_src = IPAddr("10.0.0.1")
fm.match.nw_dst = IPAddr("10.0.0.5")
fm.actions.append(of.ofp_action_output( port = 2 ) )
event.connection.send( fm )
However, when I ping from 10.0.0.1 to 10.0.0.5 there's no reply. What can be the problem ? (I've also added symmetric flow for the ICMP reply)
Thank you
Upvotes: 4
Views: 5450
Reputation: 3109
(Note: I changed 10.0.0.5
to 10.0.0.3
in the following examples, as I tested with a 1 switch, 3 hosts topology in mininet.)
Your problem is that ARP requests are not getting through. You'll need to add two additional rules to let messages of dl_type=0x0806 through. So:
def _handle_ConnectionUp (event):
fm = of.ofp_flow_mod()
fm.match.in_port = 1
fm.priority = 33001
fm.match.dl_type = 0x0800
fm.match.nw_src = IPAddr("10.0.0.1")
fm.match.nw_dst = IPAddr("10.0.0.3")
fm.actions.append(of.ofp_action_output( port = 3 ) )
event.connection.send( fm )
fm = of.ofp_flow_mod()
fm.match.in_port = 3
fm.priority = 33001
fm.match.dl_type = 0x0800
fm.match.nw_src = IPAddr("10.0.0.3")
fm.match.nw_dst = IPAddr("10.0.0.1")
fm.actions.append(of.ofp_action_output( port = 1 ) )
event.connection.send( fm )
fm = of.ofp_flow_mod()
fm.match.in_port = 1
fm.priority = 33001
fm.match.dl_type = 0x0806
fm.actions.append(of.ofp_action_output( port = 3 ) )
event.connection.send( fm )
fm = of.ofp_flow_mod()
fm.match.in_port = 3
fm.priority = 33001
fm.match.dl_type = 0x0806
fm.actions.append(of.ofp_action_output( port = 1 ) )
event.connection.send( fm )
If you don't have any loops in your network, you can also just add a single rule that floods the packets on every port except the one it came from.
fm = of.ofp_flow_mod()
fm.priority = 33001
fm.match.dl_type = 0x0806
fm.actions.append(of.ofp_action_output( port = of.OFPP_FLOOD ) )
event.connection.send( fm )
Some more information: When you send an ICMP echo request destined towards an IP address, the following happens:
If the initial query yields no response, the ICMP packet is not sent as the host does not know where to send it next. You can see this in the tcpdump
example at the end of this answer.
This is the output from mininet:
mininet@mininet-vm:~$ sudo mn --topo single,3 --mac --switch ovsk,protocols=OpenFlow10 --controller remote
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2 h3
*** Adding switches:
s1
*** Adding links:
(h1, s1) (h2, s1) (h3, s1)
*** Configuring hosts
h1 h2 h3
*** Starting controller
c0
*** Starting 1 switches
s1 ...
*** Starting CLI:
mininet> pingall
*** Ping: testing ping reachability
h1 -> X h3
h2 -> X X
h3 -> h1 X
*** Results: 66% dropped (2/6 received)
mininet>
So what if we already "know" what the next hop is? In this case we can tell ping
to send the ICMP IPv4 packet out a specific interface. It will not use ARP then. However, the receiver of the ping request will still try to use ARP to figure out how to send the response. The request will arrive, but the response will not.
You can force the initial ping to be sent to a specific interface, without using an ARP request by running:
# Run this on host h1
h1 ping -I h1-eth0 -c1 10.0.0.3
Then the initial ICMP packet will also go through even if you do not have ARP rules setup (as the nw_src
and nw_dst
match). If you run tcpdump
on h3 (Run xterm h3
and in the new terminal tcpdump
), you can see that the ICMP message arrives in this case, but the return message does not.
# Run this on host h3
root@mininet-vm:~# tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on h3-eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
20:20:19.428465 IP 10.0.0.1 > 10.0.0.3: ICMP echo request, id 24690, seq 1, length 64
20:20:19.428481 ARP, Request who-has 10.0.0.1 tell 10.0.0.3, length 28
20:20:20.428094 ARP, Request who-has 10.0.0.1 tell 10.0.0.3, length 28
20:20:21.428097 ARP, Request who-has 10.0.0.1 tell 10.0.0.3, length 28
The long sequence of ARP requests at the end is the receiving host trying to figure out over which interface it should send the response back.
Upvotes: 5