Setting ICMP match with POX controller

5.1k views Asked by At


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

1

There are 1 answers

4
jmiserez On BEST ANSWER

(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:

  • The hosts sends out an ARP request ("who has IP 10.0.0.3?") to find out the hardware MAC address for the next hop.
  • The host then sends out the ICMP packet towards the next hop.

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.