Пример #1
0
    def __init__(self, dpid):
        if not dpid:
            raise AssertionError("OpenFlowSwitch should have dpid")

        Switch.__init__(self, id=dpid)
        EventMixin.__init__(self)
        self.dpid = dpid
        self.ports = {}
        self.flow_table = NOMFlowTable(self)
        self.capabilities = 0
        self._connection = None
        self._listeners = []
        self._reconnectTimeout = None  # Timer for reconnection
        self.xid_generator = xid_generator(((dpid & 0x7FFF) << 16) + 1)
Пример #2
0
 def __init__ (self, dpid=None, **kw):
   Switch.__init__(self)#, id=dpid)
   EventMixin.__init__(self)
   self.dpid = dpid
   #self.ports = {}
   self.flow_table = NOMFlowTable(self)
   self.capabilities = 0
   self._connection = None
   self._listeners = []
   self._reconnectTimeout = None # Timer for reconnection
   self._xid_generator = xid_generator( ((self.dpid & 0x7FFF) << 16) + 1)
Пример #3
0
  def __init__ (self, dpid):
    if not dpid:
      raise AssertionError("OpenFlowSwitch should have dpid")

    Switch.__init__(self, id=dpid)
    EventMixin.__init__(self)
    self.dpid = dpid
    self.ports = {}
    self.flow_table = NOMFlowTable(self)
    self.capabilities = 0
    self._connection = None
    self._listeners = []
    self._reconnectTimeout = None # Timer for reconnection
    self.xid_generator = xid_generator( ((dpid & 0x7FFF) << 16) + 1)
Пример #4
0
class OpenFlowSwitch (EventMixin, Switch):
  """
  OpenFlowSwitches are Topology entities (inheriting from topology.Switch)
  
  OpenFlowSwitches are persistent; that is, if a switch reconnects, the
  Connection field of the original OpenFlowSwitch object will simply be
  reset to refer to the new connection.
  
  For now, OpenFlowSwitch is primarily a proxy to its underlying connection
  object. Later, we'll possibly add more explicit operations the client can
  perform.
  
  Note that for the purposes of the debugger, we can interpose on
  a switch entity by enumerating all listeners for the events listed
  below, and triggering mock events for those listeners.
  """
  _eventMixin_events = set([
    SwitchJoin, # Defined in pox.topology
    SwitchLeave,
    SwitchConnectionUp,
    SwitchConnectionDown,

    PortStatus, # Defined in libopenflow_01
    FlowRemoved,
    PacketIn,
    BarrierIn,
  ])

  def __init__ (self, dpid):
    if not dpid:
      raise AssertionError("OpenFlowSwitch should have dpid")

    Switch.__init__(self, id=dpid)
    EventMixin.__init__(self)
    self.dpid = dpid
    self.ports = {}
    self.flow_table = NOMFlowTable(self)
    self.capabilities = 0
    self._connection = None
    self._listeners = []
    self._reconnectTimeout = None # Timer for reconnection
    self.xid_generator = xid_generator( ((dpid & 0x7FFF) << 16) + 1)

  def _setConnection (self, connection, ofp=None):
    ''' ofp - a FeaturesReply message '''
    if self._connection: self._connection.removeListeners(self._listeners)
    self._listeners = []
    self._connection = connection
    if self._reconnectTimeout is not None:
      self._reconnectTimeout.cancel()
      self._reconnectTimeout = None
    if connection is None:
      self._reconnectTimeout = Timer(RECONNECT_TIMEOUT,
                                     self._timer_ReconnectTimeout)
    if ofp is not None:
      # update capabilities
      self.capabilities = ofp.capabilities
      # update all ports 
      untouched = set(self.ports.keys())
      for p in ofp.ports:
        if p.port_no in self.ports:
          self.ports[p.port_no]._update(p)
          untouched.remove(p.port_no)
        else:
          self.ports[p.port_no] = OpenFlowPort(p)
      for p in untouched:
        self.ports[p].exists = False
        del self.ports[p]
    if connection is not None:
      self._listeners = self.listenTo(connection, prefix="con")
      self.raiseEvent(SwitchConnectionUp(switch=self, connection = connection))
    else:
      self.raiseEvent(SwitchConnectionDown(switch=self))


  def _timer_ReconnectTimeout (self):
    """ Called if we've been disconnected for RECONNECT_TIMEOUT seconds """
    self._reconnectTimeout = None
    core.topology.removeEntity(self)
    self.raiseEvent(SwitchLeave, self)

  def _handle_con_PortStatus (self, event):
    p = event.ofp.desc
    if event.ofp.reason == of.OFPPR_DELETE:
      if p.port_no in self.ports:
        self.ports[p.port_no].exists = False
        del self.ports[p.port_no]
    elif event.ofp.reason == of.OFPPR_MODIFY:
      self.ports[p.port_no]._update(p)
    else:
      assert event.ofp.reason == of.OFPPR_ADD
      assert p.port_no not in self.ports
      self.ports[p.port_no] = OpenFlowPort(p)
    self.raiseEvent(event)
    event.halt = False

  def _handle_con_ConnectionDown (self, event):
    self._setConnection(None)

  def _handle_con_PacketIn (self, event):
    self.raiseEvent(event)
    event.halt = False

  def _handle_con_BarrierIn (self, event):
    self.raiseEvent(event)
    event.halt = False

  def _handle_con_FlowRemoved (self, event):
    self.raiseEvent(event)
    self.flowTable.removeFlow(event)
    event.halt = False

  def findPortForEntity (self, entity):
    for p in self.ports.itervalues():
      if entity in p:
        return p
    return None

  @property
  def connected(self):
    return self._connection != None

  def installFlow(self, **kw):
    """ install a flow in the local flow table as well as into the associated switch """
    self.flow_table.install(TableEntry(**kw))

  def serialize (self):
    # Skip over non-serializable data, e.g. sockets
    serializable = OpenFlowSwitch(self.dpid)
    return pickle.dumps(serializable, protocol = 0)

  def send(self, *args, **kw):
    return self._connection.send(*args, **kw)

  def read(self, *args, **kw):
   return self._connection.read(*args, **kw)

  def __repr__ (self):
    return "<%s %s>" % (self.__class__.__name__, dpidToStr(self.dpid))

  @property
  def name(self):
    return repr(self)
Пример #5
0
class OpenFlowSwitch(EventMixin, Switch):
    """
  OpenFlowSwitches are Topology entities (inheriting from topology.Switch)
  
  OpenFlowSwitches are persistent; that is, if a switch reconnects, the
  Connection field of the original OpenFlowSwitch object will simply be
  reset to refer to the new connection.
  
  For now, OpenFlowSwitch is primarily a proxy to its underlying connection
  object. Later, we'll possibly add more explicit operations the client can
  perform.
  
  Note that for the purposes of the debugger, we can interpose on
  a switch entity by enumerating all listeners for the events listed
  below, and triggering mock events for those listeners.
  """
    _eventMixin_events = set([
        SwitchJoin,  # Defined in pox.topology
        SwitchLeave,
        SwitchConnectionUp,
        SwitchConnectionDown,
        PortStatus,  # Defined in libopenflow_01
        FlowRemoved,
        PacketIn,
        BarrierIn,
    ])

    def __init__(self, dpid):
        if not dpid:
            raise AssertionError("OpenFlowSwitch should have dpid")

        Switch.__init__(self, id=dpid)
        EventMixin.__init__(self)
        self.dpid = dpid
        self.ports = {}
        self.flow_table = NOMFlowTable(self)
        self.capabilities = 0
        self._connection = None
        self._listeners = []
        self._reconnectTimeout = None  # Timer for reconnection
        self.xid_generator = xid_generator(((dpid & 0x7FFF) << 16) + 1)

    def _setConnection(self, connection, ofp=None):
        ''' ofp - a FeaturesReply message '''
        if self._connection: self._connection.removeListeners(self._listeners)
        self._listeners = []
        self._connection = connection
        if self._reconnectTimeout is not None:
            self._reconnectTimeout.cancel()
            self._reconnectTimeout = None
        if connection is None:
            self._reconnectTimeout = Timer(RECONNECT_TIMEOUT,
                                           self._timer_ReconnectTimeout)
        if ofp is not None:
            # update capabilities
            self.capabilities = ofp.capabilities
            # update all ports
            untouched = set(self.ports.keys())
            for p in ofp.ports:
                if p.port_no in self.ports:
                    self.ports[p.port_no]._update(p)
                    untouched.remove(p.port_no)
                else:
                    self.ports[p.port_no] = OpenFlowPort(p)
            for p in untouched:
                self.ports[p].exists = False
                del self.ports[p]
        if connection is not None:
            self._listeners = self.listenTo(connection, prefix="con")
            self.raiseEvent(
                SwitchConnectionUp(switch=self, connection=connection))
        else:
            self.raiseEvent(SwitchConnectionDown(switch=self))

    def _timer_ReconnectTimeout(self):
        """ Called if we've been disconnected for RECONNECT_TIMEOUT seconds """
        self._reconnectTimeout = None
        core.topology.removeEntity(self)
        self.raiseEvent(SwitchLeave, self)

    def _handle_con_PortStatus(self, event):
        p = event.ofp.desc
        if event.ofp.reason == of.OFPPR_DELETE:
            if p.port_no in self.ports:
                self.ports[p.port_no].exists = False
                del self.ports[p.port_no]
        elif event.ofp.reason == of.OFPPR_MODIFY:
            self.ports[p.port_no]._update(p)
        else:
            assert event.ofp.reason == of.OFPPR_ADD
            assert p.port_no not in self.ports
            self.ports[p.port_no] = OpenFlowPort(p)
        self.raiseEvent(event)
        event.halt = False

    def _handle_con_ConnectionDown(self, event):
        self._setConnection(None)

    def _handle_con_PacketIn(self, event):
        self.raiseEvent(event)
        event.halt = False

    def _handle_con_BarrierIn(self, event):
        self.raiseEvent(event)
        event.halt = False

    def _handle_con_FlowRemoved(self, event):
        self.raiseEvent(event)
        self.flowTable.removeFlow(event)
        event.halt = False

    def findPortForEntity(self, entity):
        for p in self.ports.itervalues():
            if entity in p:
                return p
        return None

    @property
    def connected(self):
        return self._connection != None

    def installFlow(self, **kw):
        """ install a flow in the local flow table as well as into the associated switch """
        self.flow_table.install(TableEntry(**kw))

    def serialize(self):
        # Skip over non-serializable data, e.g. sockets
        serializable = OpenFlowSwitch(self.dpid)
        return pickle.dumps(serializable, protocol=0)

    def send(self, *args, **kw):
        return self._connection.send(*args, **kw)

    def read(self, *args, **kw):
        return self._connection.read(*args, **kw)

    def __repr__(self):
        return "<%s %s>" % (self.__class__.__name__, dpidToStr(self.dpid))

    @property
    def name(self):
        return repr(self)