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
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
def decode_flow_table(self, json): ft = FlowTable() for e in json["entries"]: ft.add_entry(self.decode_entry(e)) return ft
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
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