Hi, everyone I made topology having 4 switches and two hosts are connected
with each switch. Here is my code for pox . By adding firewall I can
redirect traffic from s1,s2,s3 to ping h1 to h6. In topology links are as
S1-->S2--->S3--->S4-->S1
Is it possible I send ping request from S1-- >S2..>S3 nd get reply from
S3-->S4--->S1 ?? Does anybody know

Red showing description and yellow showing important parts of code



from pox.lib.revent import *

from pox.lib.util import dpidToStr

from pox.lib.addresses import EthAddr

from collections import namedtuple

import os



import csv

from pox.core import core

import pox.openflow.libopenflow_01 as of

from pox.lib.util import dpid_to_str

from pox.lib.util import str_to_bool

import time



log = core.getLogger()



# We don't want to flood immediately when a switch connects.

# Can be overriden on commandline.

_flood_delay = 0



class LearningSwitch (object):





  In short, our algorithm looks like this:



  For each packet from the switch:

  1) Use source address and switch port to update address/port table





  2) Port for destination address in our address/port table?

     No:

        2a) Flood the packet

            DONE



  3) Install flow table entry in the switch so that this

     flow goes out the appopriate port

     3a) Send the packet out appropriate port

  """

  def __init__ (self, connection, transparent):

    # Switch we'll be adding L2 learning switch capabilities to

    self.connection = connection

    self.transparent = transparent



    # Our table

    self.macToPort = {}



    # our firewall table

    self.firewall = {}



    #Add couple of rules





    self.AddRule('00-00-00-00-00-01',EthAddr('00:00:00:00:00:06'))

    self.AddRule('00-00-00-00-00-02',EthAddr('00:00:00:00:00:06'))

    self.AddRule('00-00-00-00-00-03',EthAddr('00:00:00:00:00:06'))

    self.AddRule('00-00-00-00-00-01',EthAddr('00:00:00:00:00:01'))

    self.AddRule('00-00-00-00-00-02',EthAddr('00:00:00:00:00:01'))

    self.AddRule('00-00-00-00-00-03',EthAddr('00:00:00:00:00:01'))

This upper yellow box adds the rules. This is the code which allows above
sources on dpids. So now traffic won't go from S4 if we ping h1 to h6

  # We want to hear PacketIn messages, so we listen

    connection.addListeners(self)



    # We just use this to know when to log a helpful message

    self.hold_down_expired = _flood_delay == 0





  def AddRule(self,dpidstr ,src =0 ,value=True):



      self.firewall[(dpidstr,src)] =value

      log.debug("Adding Firewall rule in %s switch of source
:%s",dpidstr,src)



  def CheckRule(self,dpidstr,src):

     try:

       entry =self.firewall[(dpidstr,src)]



       if(entry == True):

         log.debug("Rule for source (%s) found in switch %s is:FORWARD
",src,dpidstr)

       else:

         log.debug("Rule fpr source (%s) found in switch  %s is
:DROP",src,dpidstr)

         return entry

     except KeyError:

       log.debug("Rule (%s) found in %s:DROP",src,dpidstr)

       return False















  def _handle_PacketIn (self, event):

    """

    Handle packet in messages from the switch to implement above algorithm.

    """



    packet = event.parsed



    def flood (message = None):

      """ Floods the packet """

      msg = of.ofp_packet_out()

      msg.actions.append(of.ofp_action_output(port = of.OFPP_FLOOD))

      msg.data = event.ofp

      msg.in_port = event.port

      self.connection.send(msg)



    def drop (duration = None):

      """

      Drops this packet and optionally installs a flow to continue

      dropping similar ones for a while

      """

      if duration is not None:

        if not isinstance(duration, tuple):

          duration = (duration,duration)

        msg = of.ofp_flow_mod()

        msg.match = of.ofp_match.from_packet(packet)



        msg.idle_timeout = duration[0]

        msg.hard_timeout = duration[1]

        msg.buffer_id = event.ofp.buffer_id

        self.connection.send(msg)

      elif event.ofp.buffer_id is not None:

        msg = of.ofp_packet_out()

        msg.buffer_id = event.ofp.buffer_id

        msg.in_port = event.port

        self.connection.send(msg)



    self.macToPort[packet.src] = event.port # 1

This line stores the port against mac for further destination.



#additional code



    dpidstr =dpid_to_str(event.connection.dpid)

 #Check firewall rules

    if self.CheckRule(dpidstr,packet.src) == False:

        drop()

        return









    if packet.dst not in self.macToPort: # 2

        flood("Port for %s unknown -- flooding" % (packet.dst,)) # 2a

    else:

        port = self.macToPort[packet.dst]

It takes port from macToPort table against destination.





        log.debug("installing flow for source %s on incoming port .%i ->
destination is %s. on destination port%i" %

                  (packet.src, event.port, packet.dst, port))

        msg = of.ofp_flow_mod()

        msg.match = of.ofp_match.from_packet(packet, event.port)

        msg.idle_timeout = 10

        msg.hard_timeout = 30

        msg.actions.append(of.ofp_action_output(port = port))

        msg.data = event.ofp # 3

        self.connection.send(msg)





class l2_learning (object):

  """

  Waits for OpenFlow switches to connect and makes them learning switches.

  """

  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))







Regards
Uzma Waheed
MSIT-14
SEECS ( NUST )



-- 
Regards
Uzma Waheed
MSIT-14
SEECS ( NUST )

Reply via email to