1
votes

I’m a beginner in python and pox controller. I want to add a code to the pox, to categorize the received packets. I want it to count IP packets travelling between a source & a destination IP/port pair and with identical protocols within a certain period of time. I want a list like this:

[ [Src ip , ds tip, src port , dst port , protocol=tcp , flow count=x]

[Src ip , ds tip, src port , dst port , protocol=IP , flow count=y]

[ Src ip , ds tip, src port , dst port , protocol=ICMP , flow count=z] ]

I used a list of lists in python , it means 1 list per flow. And I added the flow counting section of the code to the L2_learning component of pox (inside the _handle_PacketIn function). So every time a packet_in is received in the controller, the computation will be executed.

But I got an error: RuntimeError: maximum recursion depth exceeded.

I have not used any recursion function in the code! I have even incremented the stack depth allowed, but the error still exists.

In addition,i don’t know how to schedule the program to fill the list of lists(named: flowlist) at particular time intervals, I’m a bit confused, because every packet that comes to the controller, should be considered in this computation, on the other hand, computing for every packet causes the mentioned error!

Could you please tell me how to compute the flow count(described above) at particular intervals? And where to place the code for this scheduling in my program?

Where to place the command for printing the flowlist, to only print the completed list at that time interval, not printing the list every time a packet is received in controller.

And how to solve the (maximum recursion depth exceeded) error?

Here is the code:

sys.setrecursionlimit(10000)
class LearningSwitch (object):
flowlist=[]
  def __init__ (self, connection, transparent):
 .......
    LearningSwitch.flowlist=[]
  def _handle_PacketIn (self, event):
   flag=0
   packet = event.parsed
   if packet.type == packet.IP_TYPE:
     ip_packet=packet.payload
             #-------------TCP-----------------
     if (packet.find('tcp')):
       tcp_packet = ip_packet.payload

       for thisflow in LearningSwitch.flowlist:

          if (thisflow[0]==packet.next.srcip and thisflow[1]==packet.next.dstip and thisflow [2]==tcp_packet.srcport and thisflow[3]==tcp_packet.dstport,thisflow[4]== "TCP"):

            thisflow[5]+=1
            flag=1
       if (flag!=1):
              LearningSwitch.flowlist.append([packet.next.srcip,packet.next.dstip,tcp_packet.srcport,tcp_packet.dstport,"TCP",1])

             #---------- ICMP --------------------
     elif (packet.find('icmp')):
      icmp_packet = ip_packet.payload   
      for thisflow in LearningSwitch.flowlist:

        if (thisflow[0]==ip_packet.srcip and thisflow[1]==ip_packet.dstip and  thisflow[4]== "ICMP"):

            thisflow[5]+=1
            flag=1
      if (flag!=1):
         LearningSwitch.flowlist.append([packet.next.srcip,packet.next.dstip,"--","--","ICMP",1])
             #------------ IPV4 ---------------------
     elif (packet.find('ipv4')):

       for thisflow in LearningSwitch.flowlist:

         if (thisflow[0]==packet.next.srcip and thisflow[1]==packet.next.dstip and  thisflow[4]== "IP"):

            thisflow[5]+=1
            flag=1
       if (flag!=1):
         LearningSwitch.flowlist.append([packet.next.srcip,packet.next.dstip,"--","--","IP",1])


   print LearningSwitch.flowlist
          #---- The rest of the code is from L2_learning component

.
.
.
.


class l2_learning (object):

  def __init__ (self, transparent):
    core.openflow.addListeners(self)
    self.transparent = transparent

  def _handle_ConnectionUp (self, event):
     log.debug("Connection %s" % (event.connection,))
     LearningSwitch(event.connection, self.transparent)


def launch (transparent=False, hold_down=_flood_delay):
    """
     Starts an L2 learning switch.
    """
 try:
   global _flood_delay
   _flood_delay = int(str(hold_down), 10)
   assert _flood_delay >= 0
 except:
   raise RuntimeError("Expected hold-down to be a number")

core.registerNew(l2_learning, str_to_bool(transparent))

This is the error:

    return -other.__cmp__(self)
  File "/home/manager/pox/pox/lib/addresses.py", line 347, in __cmp__
    return -other.__cmp__(self)
  File "/home/manager/pox/pox/lib/addresses.py", line 214, in __cmp__
    return -other.__cmp__(self)
  File "/home/manager/pox/pox/lib/addresses.py", line 347, in __cmp__
    return -other.__cmp__(self)
  File "/home/manager/pox/pox/lib/addresses.py", line 214, in __cmp__
    return -other.__cmp__(self)
  File "/home/manager/pox/pox/lib/addresses.py", line 347, in __cmp__
    return -other.__cmp__(self)
  File "/home/manager/pox/pox/lib/addresses.py", line 214, in __cmp__
    return -other.__cmp__(self)
  File "/home/manager/pox/pox/lib/addresses.py", line 347, in __cmp__
    return -other.__cmp__(self)
  File "/home/manager/pox/pox/lib/addresses.py", line 214, in __cmp__
   return -other.__cmp__(self)
RuntimeError: maximum recursion depth exceeded

Thank you for your kind help.

1
Are there any more details in the actual error that can point to where the recursion is happening? Maybe the pox code has a recursive section causing the error.nbryans
Can you post the exact error message ?SotirisTsartsaris
I edited my post and added the error.you can also see the-- whole --code i have added to the pox,in my post. i have not used any recursion function. when i execute for example, a ping command in mininet, the error occurs.F. gh
I even deleted the "print" command, but the error remained. It is probably related to filling the list of lists( flowlist in the code)F. gh
If you run with mininet post the script for the network setup or the command you use to run mininet because I can not reproduce your error. It gives me results as expected [[IPAddr('10.0.0.1'), IPAddr('10.0.0.2'), '--', '--', 'ICMP', 4], [IPAddr('10.0.0.2'), IPAddr('10.0.0.1'), '--', '--', 'ICMP', 4]] SotirisTsartsaris

1 Answers

0
votes

In order to have a recurring function you need the Timer class from the recoco module. First import Timer

from pox.lib.recoco import Timer

Create a function that will print the list. This function belongs in the

class LearningSwitch (object):

So it is a method of this class and we can refer to it later with self.

  def print_list(self):
    """
    just print the list
    Returns:
            nada
    """
    if LearningSwitch.flowlist:
      print LearningSwitch.flowlist

Then we create a function that will call every dt seconds the print function above. Passing params the seconds passed between each call

  def _timer_func(self, dt):
    """
    recurring function, calls a function every dt seconds
    Returns:
            nada
    """
    Timer(dt, self.print_list, recurring=True)

Finally we call the _timer_func in the init of the class

self._timer_func(2)

Passing here 2 seconds. Delete the print from _handle_PacketIn. You don't need it anymore. The complete code can be found here

The command for mininet used is

sudo mn --controller=remote