def decode_entry(self, json): e = TableEntry() for (k, v) in json.iteritems(): if k == "match": e.match = self.decode_match(v) elif k == "actions": e.actions = [ self.decode_action(a) for a in v ] else: setattr(e, k, v) return e
def decode_entry(self, json): e = TableEntry() for (k, v) in json.iteritems(): if k == "match": e.match = self.decode_match(v) elif k == "actions": e.actions = [self.decode_action(a) for a in v] else: setattr(e, k, v) return e
def __init__(self, priority=of.OFP_DEFAULT_PRIORITY, cookie=0, idle_timeout=0, hard_timeout=0, flags=0, match=None, actions=[], buffer_id=None, now=None, apps=None, command=None, dpid=None): if match is None: match = of.ofp_match() TableEntry.__init__(self, priority, cookie, idle_timeout, hard_timeout, flags, match, actions, buffer_id, now) self.tag = TableEntryTag(apps) self.command = command self.dpid = dpid self.entry_name = "ofp_flow_mod"
def _flow_mod_add(self, flow_mod, connection, table): """ Process an OFPFC_ADD flow mod sent to the switch. """ match = flow_mod.match priority = flow_mod.priority new_entry = TableEntry.from_flow_mod(flow_mod) if flow_mod.flags & OFPFF_CHECK_OVERLAP: if table.check_for_overlapping_entry(new_entry): # Another entry overlaps. Do not add. self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_OVERLAP, ofp=flow_mod, connection=connection) return if flow_mod.command == OFPFC_ADD: # Exactly matching entries have to be removed if OFPFC_ADD table.remove_matching_entries(match, priority=priority, strict=True) if len(table) >= self.max_entries: # Flow table is full. Respond with error message. self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_ALL_TABLES_FULL, ofp=flow_mod, connection=connection) return table.add_entry(new_entry)
def _flow_mod_add(self, flow_mod, connection, table): """ Process an OFPFC_ADD flow mod sent to the switch. """ match = flow_mod.match priority = flow_mod.priority new_entry = TableEntry.from_flow_mod(flow_mod) if flow_mod.flags & OFPFF_CHECK_OVERLAP: if table.check_for_overlapping_entry(new_entry): # Another entry overlaps. Do not add. self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_OVERLAP, ofp=flow_mod, connection=connection) return if flow_mod.command == OFPFC_ADD: # Exactly matching entries have to be removed if OFPFC_ADD table.remove_matching_entries(match, priority=priority, strict=True) if len(table) >= self.max_entries: # Flow table is full. Respond with error message. self.send_error( type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_ALL_TABLES_FULL, ofp=flow_mod, connection=connection ) return table.add_entry(new_entry)
def removeFlow(self, msg): """remove flow entry. msg[flow_mod] -- entry msg object. """ tabEntry = TableEntry.from_flow_mod(msg) log.info("remove entry - %s" % str(tabEntry)) self.flow_table.remove_with_wildcards(tabEntry)
def installFlow(self, msg): """@override because base class has bug. no import TableEntry... and extend input struct to flow_mod object. """ tabEntry = TableEntry.from_flow_mod(msg) log.info("apply entry - %s" % str(tabEntry)) self.flow_table.install(tabEntry)
def _flow_mod_add (self, flow_mod, connection, table): """ Process an OFPFC_ADD flow mod sent to the switch. """ match = flow_mod.match priority = flow_mod.priority if flow_mod.flags & OFPFF_EMERG: if flow_mod.idle_timeout != 0 or flow_mod.hard_timeout != 0: # Emergency flow mod has non-zero timeouts. Do not add. self.log.warn("Rejecting emergency flow with nonzero timeout") self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_BAD_EMERG_TIMEOUT, ofp=flow_mod, connection=connection) return if flow_mod.flags & OFPFF_SEND_FLOW_REM: # Emergency flows can't send removal messages, we we might want to # reject this early. Sadly, there's no error code for this, so we just # abuse EPERM. If we eventually support Nicira extended error codes, # we should use one here. self.log.warn("Rejecting emergency flow with flow removal flag") self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_EPERM, ofp=flow_mod, connection=connection) return #NOTE: An error is sent anyways because the current implementation does # not support emergency entries. self.log.warn("Rejecting emergency flow (not supported)") self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_ALL_TABLES_FULL, ofp=flow_mod, connection=connection) return #FELIPE TOMM - TCC #AQUI CHAMA A FUNCAO QUE VERIFICA SE JA EXISTE UMA REGRA IGUAL new_entry = TableEntry.from_flow_mod(flow_mod) log = core.getLogger() log.debug("Entrou _FLOW_MOD_ADD") if flow_mod.flags & OFPFF_CHECK_OVERLAP: log.debug("Entrou _FLOW_MOD_ADD - 1 if") if table.check_for_overlapping_entry(new_entry): # Another entry overlaps. Do not add. log.debug("Entrou _FLOW_MOD_ADD - 1 if") self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_OVERLAP, ofp=flow_mod, connection=connection) return if flow_mod.command == OFPFC_ADD: # Exactly matching entries have to be removed if OFPFC_ADD table.remove_matching_entries(match, priority=priority, strict=True) if len(table) >= self.max_entries: # Flow table is full. Respond with error message. self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_ALL_TABLES_FULL, ofp=flow_mod, connection=connection) return table.add_entry(new_entry)
def _flow_mod_add (self, flow_mod, connection, table): """ Process an OFPFC_ADD flow mod sent to the switch. """ match = flow_mod.match priority = flow_mod.priority if flow_mod.flags & OFPFF_EMERG: if flow_mod.idle_timeout != 0 or flow_mod.hard_timeout != 0: # Emergency flow mod has non-zero timeouts. Do not add. self.log.warn("Rejecting emergency flow with nonzero timeout") self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_BAD_EMERG_TIMEOUT, ofp=flow_mod, connection=connection) return if flow_mod.flags & OFPFF_SEND_FLOW_REM: # Emergency flows can't send removal messages, we we might want to # reject this early. Sadly, there's no error code for this, so we just # abuse EPERM. If we eventually support Nicira extended error codes, # we should use one here. self.log.warn("Rejecting emergency flow with flow removal flag") self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_EPERM, ofp=flow_mod, connection=connection) return #NOTE: An error is sent anyways because the current implementation does # not support emergency entries. self.log.warn("Rejecting emergency flow (not supported)") self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_ALL_TABLES_FULL, ofp=flow_mod, connection=connection) return new_entry = TableEntry.from_flow_mod(flow_mod) if flow_mod.flags & OFPFF_CHECK_OVERLAP: if table.check_for_overlapping_entry(new_entry): # Another entry overlaps. Do not add. self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_OVERLAP, ofp=flow_mod, connection=connection) return if flow_mod.command == OFPFC_ADD: # Exactly matching entries have to be removed if OFPFC_ADD table.remove_matching_entries(match, priority=priority, strict=True) if len(table) >= self.max_entries: # Flow table is full. Respond with error message. self.send_error(type=OFPET_FLOW_MOD_FAILED, code=OFPFMFC_ALL_TABLES_FULL, ofp=flow_mod, connection=connection) return table.add_entry(new_entry)
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 installFlow(self, **kw): """ install flow in the local table and the associated switch """ self.flow_table.install(TableEntry(**kw))
def _createMesh(self, dst, graph, *args, **kwargs): protocol = kwargs.get(PROTOCOL) if protocol is None: protocol = ethernet.IP_TYPE dstinfo = self._resolveInfo(dst, kwargs.get(DSTMAC), kwargs.get(DSTIP), kwargs.get(DSTDPID), kwargs.get(OUTPORT), protocol, "dst") if dstinfo is None: return None dst, dstmac, dstip, dstdpid, outport = dstinfo outputinfo = self._resolveOutputInfo(dstdpid, outport, protocol, **kwargs) if outputinfo is None: return None outport, dstdpid, ipProtocol, srcport, dstport, tos = outputinfo msg = self.createMessage(protocol, None, dstip, ipProtocol) msg.idle_timeout = kwargs.get(IDLE_TIMEOUT, of.OFP_FLOW_PERMANENT) msg.hard_timeout = kwargs.get(HARD_TIMEOUT, of.OFP_FLOW_PERMANENT) msg.actions = [ of.ofp_action_dl_addr.set_dst(dstmac), of.ofp_action_output(port=outport, max_len=0) ] mesh = self.mesh[dst] # Flow to the node from the adjacent switch if dstdpid not in mesh.keys(): # send message to switch ofs = core.topology.getOFS(dstdpid) tabEntry = TableEntry.from_flow_mod(msg) ofs.flow_table.install(tabEntry) mesh[dstdpid] = 0 msg.match.nw_tos = 0 # Flow to the adjacent switch from other switches for sw in core.topology.getSwitchs(): if dstdpid == sw.dpid: continue if sw.dpid in mesh.keys(): continue via = self.getVia(sw.dpid, dstdpid, None, graph) route = ScnRoute() route.links = via route.path = Path.create(None, dst, **kwargs) for link in via: msg.actions = [of.ofp_action_output(port=link.ofp1.number, max_len=0)] # send message to switch ofs = link.ofs1 tabEntry = TableEntry.from_flow_mod(msg) route.entries[ofs] = tabEntry # rewrite dst mac if last switch != first switch msg.actions = [ of.ofp_action_dl_addr.set_dst(dstmac), of.ofp_action_output(port=outport, max_len=0) ] # send message to switch ofs = core.topology.getOFS(dstdpid) tabEntry = TableEntry.from_flow_mod(msg) # use for jsonLogger route.lastEntity = tabEntry.actions[1] log.debug('a route should have been created') self.addRoute(route) mesh[sw.dpid] = route.cookie
def createRoute(self, src, dst, *args, **kwargs): """ src = EthAddr or str or IPAddr or Host dst = EthAddr or str or IPAddr or Host srcdpid = switch id (integer) or Switch inport = switch port (integer) or SwitchPort #via = [(dpid, port), (dpid), (dpid), (dpid, port), ...] via = ScnLinks #gateway = (dpid, port) gateway = SwitchPort tos = ip tos (integer) protocol = ethernet.IP_TYPE etc... ipProtocol = ipv4.TCP_PROTOCOL or ipv4.UDP_PROTOCOL etc... kwargs = etc... """ protocol = kwargs.get(PROTOCOL) if protocol is None: protocol = ethernet.IP_TYPE srcinfo = self._resolveInfo(src, kwargs.get(SRCMAC), kwargs.get(SRCIP), kwargs.get(SRCDPID), kwargs.get(INPORT), protocol, "src") dstinfo = self._resolveInfo(dst, kwargs.get(DSTMAC), kwargs.get(DSTIP), kwargs.get(DSTDPID), kwargs.get(OUTPORT), protocol, "dst") if srcinfo is None or dstinfo is None: return None src, srcmac, srcip, srcdpid, inport = srcinfo dst, dstmac, dstip, dstdpid, outport = dstinfo outputinfo = self._resolveOutputInfo(dstdpid, outport, protocol, **kwargs) if outputinfo is None: return None outport, dstdpid, ipProtocol, srcport, dstport, tos = outputinfo via = kwargs.get(VIA) conditions = kwargs.get(RoutingConditions.MainKey) if srcdpid == dstdpid: via = self.getLocalVia(srcdpid, srcip, dstdpid, dstip) if via is None or self.forceRoute: minBw = None if conditions is not None: minBw = conditions.get(RoutingConditions.bandwidth) via = self.getVia(srcdpid, dstdpid, minBw) log.debug("via (scnLinks) => \n%s" % str(via)) route = ScnRoute() route.links = ScnLinks(via) route.conditions = conditions route.path = Path.create(src, dst, **kwargs) # DO NOT REWRITE MAC ADDRESSES BETWEEN THE SWITCHES # ONLY THE LAST SWITCH WILL CHANGE THE DESTINATION MAC msg = self.createMessage(protocol, srcip, dstip, ipProtocol, srcport, dstport, tos) msg.idle_timeout = kwargs.get(IDLE_TIMEOUT, of.OFP_FLOW_PERMANENT) msg.hard_timeout = kwargs.get(HARD_TIMEOUT, of.OFP_FLOW_PERMANENT) for link in via: msg.actions = [of.ofp_action_output(port=link.ofp1.number, max_len=0)] # send message to switch ofs = link.ofs1 tabEntry = TableEntry.from_flow_mod(msg) route.entries[ofs] = tabEntry # rewrite dst mac if last switch != first switch msg.actions = [ of.ofp_action_dl_addr.set_dst(dstmac), of.ofp_action_output(port=outport, max_len=0) ] # send message to switch ofs = core.topology.getOFS(dstdpid) tabEntry = TableEntry.from_flow_mod(msg) route.lastEntity = tabEntry.actions[1] log.debug('a route should have been created') return route
def installFlow(self, **kw): """ install flow in the local table and the associated switch """ #FELIPE TOMM - TCC print "OPENFLOW/TOPOLOGY.PY - OpenFlowSwitch - INSTALLFLOW" self.flow_table.install(TableEntry(**kw))