Exemple #1
0
def GenerateACL():
    acl_rules = open(r'..\Data\acl3_4k_rules.txt')
    table = FlowTable()
    i = 3874
    while True:
        r = acl_rules.readline().split()
        if not r: break
        table.add_entry(
            TableEntry(priority=i,
                       cookie=0x1,
                       match=ofp_match(dl_src=EthAddr("00:00:00:00:00:01"),
                                       nw_src=r[0],
                                       nw_dst=r[1]),
                       actions=[ofp_action_output(port=5)]))
        #table.add_entry(TableEntry(priority=i, cookie=0x1, match=ofp_match(dl_src=EthAddr("00:00:00:00:00:01"),nw_src="53.45.14.183/32",nw_dst="18.184.25.126/32"), actions=[ofp_action_output(port=5)]))
        i = i - 1
    return table
Exemple #2
0
 def table():
     t = FlowTable()
     t.add_entry(
         TableEntry(priority=6,
                    cookie=0x1,
                    match=ofp_match(dl_src=EthAddr("00:00:00:00:00:01"),
                                    nw_src="1.2.3.4"),
                    actions=[ofp_action_output(port=5)]))
     t.add_entry(
         TableEntry(priority=5,
                    cookie=0x2,
                    match=ofp_match(dl_src=EthAddr("00:00:00:00:00:02"),
                                    nw_src="1.2.3.0/24"),
                    actions=[ofp_action_output(port=6)]))
     t.add_entry(
         TableEntry(priority=1,
                    cookie=0x3,
                    match=ofp_match(),
                    actions=[]))
     return t
Exemple #3
0
 def decode_flow_table(self, json):
   ft = FlowTable()
   for e in json["entries"]:
     ft.add_entry(self.decode_entry(e))
   return ft
Exemple #4
0
class OFSyncFlowTable (EventMixin):
  _eventMixin_events = set([FlowTableModification])
  """
  A flow table that keeps in sync with a switch
  """
  ADD = of.OFPFC_ADD
  REMOVE = of.OFPFC_DELETE
  REMOVE_STRICT = of.OFPFC_DELETE_STRICT
  TIME_OUT = 2

  def __init__ (self, switch=None, **kw):
    EventMixin.__init__(self)
    self.flow_table = FlowTable()
    self.switch = switch

    # a list of pending flow table entries : tuples (ADD|REMOVE, entry)
    self._pending = []

    # a map of pending barriers barrier_xid-> ([entry1,entry2])
    self._pending_barrier_to_ops = {}
    # a map of pending barriers per request entry -> (barrier_xid, time)
    self._pending_op_to_barrier = {}

    self.listenTo(switch)

  def install (self, entries=[]):
    """
    asynchronously install entries in the flow table

    will raise a FlowTableModification event when the change has been
    processed by the switch
    """
    self._mod(entries, OFSyncFlowTable.ADD)

  def remove_with_wildcards (self, entries=[]):
    """
    asynchronously remove entries in the flow table

    will raise a FlowTableModification event when the change has been
    processed by the switch
    """
    self._mod(entries, OFSyncFlowTable.REMOVE)

  def remove_strict (self, entries=[]):
    """
    asynchronously remove entries in the flow table.

    will raise a FlowTableModification event when the change has been
    processed by the switch
    """
    self._mod(entries, OFSyncFlowTable.REMOVE_STRICT)

  @property
  def entries (self):
    return self.flow_table.entries

  @property
  def num_pending (self):
    return len(self._pending)

  def __len__ (self):
    return len(self.flow_table)

  def _mod (self, entries, command):
    if isinstance(entries, TableEntry):
      entries = [ entries ]

    for entry in entries:
      if(command == OFSyncFlowTable.REMOVE):
        self._pending = [(cmd,pentry) for cmd,pentry in self._pending
                         if not (cmd == OFSyncFlowTable.ADD
                                 and entry.matches_with_wildcards(pentry))]
      elif(command == OFSyncFlowTable.REMOVE_STRICT):
        self._pending = [(cmd,pentry) for cmd,pentry in self._pending
                         if not (cmd == OFSyncFlowTable.ADD
                                 and entry == pentry)]

      self._pending.append( (command, entry) )

    self._sync_pending()

  def _sync_pending (self, clear=False):
    if not self.switch.connected:
      return False

    # resync the switch
    if clear:
      self._pending_barrier_to_ops = {}
      self._pending_op_to_barrier = {}
      self._pending = filter(lambda(op): op[0] == OFSyncFlowTable.ADD,
                             self._pending)

      self.switch.send(of.ofp_flow_mod(command=of.OFPFC_DELETE,
                                       match=of.ofp_match()))
      self.switch.send(of.ofp_barrier_request())

      todo = map(lambda(e): (OFSyncFlowTable.ADD, e),
                 self.flow_table.entries) + self._pending
    else:
      todo = [op for op in self._pending
              if op not in self._pending_op_to_barrier
              or (self._pending_op_to_barrier[op][1]
                  + OFSyncFlowTable.TIME_OUT) < time.time() ]

    for op in todo:
      fmod_xid = self.switch._xid_generator()
      flow_mod = op[1].to_flow_mod(xid=fmod_xid, command=op[0],
                                   flags=op[1].flags | of.OFPFF_SEND_FLOW_REM)
      self.switch.send(flow_mod)

    barrier_xid = self.switch._xid_generator()
    self.switch.send(of.ofp_barrier_request(xid=barrier_xid))
    now = time.time()
    self._pending_barrier_to_ops[barrier_xid] = todo

    for op in todo:
      self._pending_op_to_barrier[op] = (barrier_xid, now)

  def _handle_SwitchConnectionUp (self, event):
    # sync all_flows
    self._sync_pending(clear=True)

  def _handle_SwitchConnectionDown (self, event):
    # connection down. too bad for our unconfirmed entries
    self._pending_barrier_to_ops = {}
    self._pending_op_to_barrier = {}

  def _handle_BarrierIn (self, barrier):
    # yeah. barrier in. time to sync some of these flows
    if barrier.xid in self._pending_barrier_to_ops:
      added = []
      removed = []
      #print "barrier in: pending for barrier: %d: %s" % (barrier.xid,
      #    self._pending_barrier_to_ops[barrier.xid])
      for op in self._pending_barrier_to_ops[barrier.xid]:
        (command, entry) = op
        if(command == OFSyncFlowTable.ADD):
          self.flow_table.add_entry(entry)
          added.append(entry)
        else:
          removed.extend(self.flow_table.remove_matching_entries(entry.match,
              entry.priority, strict=command == OFSyncFlowTable.REMOVE_STRICT))
        #print "op: %s, pending: %s" % (op, self._pending)
        if op in self._pending: self._pending.remove(op)
        self._pending_op_to_barrier.pop(op, None)
      del self._pending_barrier_to_ops[barrier.xid]
      self.raiseEvent(FlowTableModification(added = added, removed=removed))
      return EventHalt
    else:
      return EventContinue

  def _handle_FlowRemoved (self, event):
    """
    process a flow removed event -- remove the matching flow from the table.
    """
    flow_removed = event.ofp
    for entry in self.flow_table.entries:
      if (flow_removed.match == entry.match
          and flow_removed.priority == entry.priority):
        self.flow_table.remove_entry(entry)
        self.raiseEvent(FlowTableModification(removed=[entry]))
        return EventHalt
    return EventContinue
Exemple #5
0
class OFSyncFlowTable (EventMixin):
  _eventMixin_events = set([FlowTableModification])
  """
  A flow table that keeps in sync with a switch
  """
  ADD = of.OFPFC_ADD
  REMOVE = of.OFPFC_DELETE
  REMOVE_STRICT = of.OFPFC_DELETE_STRICT
  TIME_OUT = 2

  def __init__ (self, switch=None, **kw):
    EventMixin.__init__(self)
    self.flow_table = FlowTable()
    self.switch = switch

    # a list of pending flow table entries : tuples (ADD|REMOVE, entry)
    self._pending = []

    # a map of pending barriers barrier_xid-> ([entry1,entry2])
    self._pending_barrier_to_ops = {}
    # a map of pending barriers per request entry -> (barrier_xid, time)
    self._pending_op_to_barrier = {}

    self.listenTo(switch)

  def install (self, entries=[]):
    """
    asynchronously install entries in the flow table

    will raise a FlowTableModification event when the change has been
    processed by the switch
    """
    self._mod(entries, OFSyncFlowTable.ADD)

  def remove_with_wildcards (self, entries=[]):
    """
    asynchronously remove entries in the flow table

    will raise a FlowTableModification event when the change has been
    processed by the switch
    """
    self._mod(entries, OFSyncFlowTable.REMOVE)

  def remove_strict (self, entries=[]):
    """
    asynchronously remove entries in the flow table.

    will raise a FlowTableModification event when the change has been
    processed by the switch
    """
    self._mod(entries, OFSyncFlowTable.REMOVE_STRICT)

  @property
  def entries (self):
    return self.flow_table.entries

  @property
  def num_pending (self):
    return len(self._pending)

  def __len__ (self):
    return len(self.flow_table)

  def _mod (self, entries, command):
    if isinstance(entries, TableEntry):
      entries = [ entries ]

    for entry in entries:
      if(command == OFSyncFlowTable.REMOVE):
        self._pending = [(cmd,pentry) for cmd,pentry in self._pending
                         if not (cmd == OFSyncFlowTable.ADD
                                 and entry.matches_with_wildcards(pentry))]
      elif(command == OFSyncFlowTable.REMOVE_STRICT):
        self._pending = [(cmd,pentry) for cmd,pentry in self._pending
                         if not (cmd == OFSyncFlowTable.ADD
                                 and entry == pentry)]

      self._pending.append( (command, entry) )

    self._sync_pending()

  def _sync_pending (self, clear=False):
    if not self.switch.connected:
      return False

    # resync the switch
    if clear:
      self._pending_barrier_to_ops = {}
      self._pending_op_to_barrier = {}
      self._pending = filter(lambda(op): op[0] == OFSyncFlowTable.ADD,
                             self._pending)

      self.switch.send(of.ofp_flow_mod(command=of.OFPFC_DELETE,
                                       match=of.ofp_match()))
      self.switch.send(of.ofp_barrier_request())

      todo = map(lambda(e): (OFSyncFlowTable.ADD, e),
                 self.flow_table.entries) + self._pending
    else:
      todo = [op for op in self._pending
              if op not in self._pending_op_to_barrier
              or (self._pending_op_to_barrier[op][1]
                  + OFSyncFlowTable.TIME_OUT) < time.time() ]

    for op in todo:
      fmod_xid = self.switch._xid_generator()
      flow_mod = op[1].to_flow_mod(xid=fmod_xid, command=op[0],
                                   flags=op[1].flags | of.OFPFF_SEND_FLOW_REM)
      self.switch.send(flow_mod)

    barrier_xid = self.switch._xid_generator()
    self.switch.send(of.ofp_barrier_request(xid=barrier_xid))
    now = time.time()
    self._pending_barrier_to_ops[barrier_xid] = todo

    for op in todo:
      self._pending_op_to_barrier[op] = (barrier_xid, now)

  def _handle_SwitchConnectionUp (self, event):
    # sync all_flows
    self._sync_pending(clear=True)

  def _handle_SwitchConnectionDown (self, event):
    # connection down. too bad for our unconfirmed entries
    self._pending_barrier_to_ops = {}
    self._pending_op_to_barrier = {}

  def _handle_BarrierIn (self, barrier):
    # yeah. barrier in. time to sync some of these flows
    if barrier.xid in self._pending_barrier_to_ops:
      added = []
      removed = []
      #print "barrier in: pending for barrier: %d: %s" % (barrier.xid,
      #    self._pending_barrier_to_ops[barrier.xid])
      for op in self._pending_barrier_to_ops[barrier.xid]:
        (command, entry) = op
        if(command == OFSyncFlowTable.ADD):
          self.flow_table.add_entry(entry)
          added.append(entry)
        else:
          removed.extend(self.flow_table.remove_matching_entries(entry.match,
              entry.priority, strict=command == OFSyncFlowTable.REMOVE_STRICT))
        #print "op: %s, pending: %s" % (op, self._pending)
        if op in self._pending: self._pending.remove(op)
        self._pending_op_to_barrier.pop(op, None)
      del self._pending_barrier_to_ops[barrier.xid]
      self.raiseEvent(FlowTableModification(added = added, removed=removed))
      return EventHalt
    else:
      return EventContinue

  def _handle_FlowRemoved (self, event):
    """
    process a flow removed event -- remove the matching flow from the table.
    """
    flow_removed = event.ofp
    for entry in self.flow_table.entries:
      if (flow_removed.match == entry.match
          and flow_removed.priority == entry.priority):
        self.flow_table.remove_entry(entry)
        self.raiseEvent(FlowTableModification(removed=[entry]))
        return EventHalt
    return EventContinue
Exemple #6
0
 def decode_flow_table(self, json):
     ft = FlowTable()
     for e in json["entries"]:
         ft.add_entry(self.decode_entry(e))
     return ft
Exemple #7
0
 def table():
   t = FlowTable()
   t.add_entry(TableEntry(priority=6, cookie=0x1, match=ofp_match(dl_src=EthAddr("00:00:00:00:00:01"),nw_src="1.2.3.4"), actions=[ofp_action_output(port=5)]))
   t.add_entry(TableEntry(priority=5, cookie=0x2, match=ofp_match(dl_src=EthAddr("00:00:00:00:00:02"), nw_src="1.2.3.0/24"), actions=[ofp_action_output(port=6)]))
   t.add_entry(TableEntry(priority=1, cookie=0x3, match=ofp_match(), actions=[]))
   return t