def mod_flow(self, datapath, flow, command): if datapath.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.mod_flow_entry(datapath, flow, command) elif datapath.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: ofctl_v1_2.mod_flow_entry(datapath, flow, command) elif datapath.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(datapath, flow, command)
def mod_flow_entry(self, req, cmd, **_kwargs): try: flow = eval(req.body) except SyntaxError: LOG.debug('invalid syntax %s', req.body) return Response(status=400) dpid = flow.get('dpid') dp = self.dpset.get(int(dpid)) if dp is None: return Response(status=404) if cmd == 'add': cmd = dp.ofproto.OFPFC_ADD elif cmd == 'modify': cmd = dp.ofproto.OFPFC_MODIFY elif cmd == 'delete': cmd = dp.ofproto.OFPFC_DELETE else: return Response(status=404) if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.mod_flow_entry(dp, flow, cmd) elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: ofctl_v1_2.mod_flow_entry(dp, flow, cmd) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(dp, flow, cmd) else: LOG.debug('Unsupported OF protocol') return Response(status=501) return Response(status=200) res = Response(content_type='application/json', body=body) res.headers.add('Access-Control-Allow-Origin', '*') return res
def delete_patch_flow(self, req_flow): # Check before send flow-mod dpid = req_flow.get("dpid") dp = self.dpset.get(dpid) if dp is None: return Response(status=400) inport = req_flow.get("inport") outport = req_flow.get("outport") mirrorport = req_flow.get("mirrorport") for flow in self.patch_flows: if dpid == flow["dpid"] and inport == flow["inport"]: break else: LOG.info("Requested inport is not used (dpid:%s, inport:%d)", dpid, inport) return Response(status=400) del_flow = {"match": {"in_port": inport}} if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.mod_flow_entry(dp, del_flow, dp.ofproto.OFPFC_DELETE) self.patch_flows.remove(req_flow) elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: ofctl_v1_2.mod_flow_entry(dp, del_flow, dp.ofproto.OFPFC_DELETE) self.patch_flows.remove(req_flow) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(dp, del_flow, dp.ofproto.OFPFC_DELETE) self.patch_flows.remove(req_flow) else: LOG.debug("Unsupported OF protocol") return Response(status=501) return Response(status=200)
def mod_flow_entry(self, req, cmd, **_kwargs): if cmd == "reset" or cmd == "reset_strict": try: flow = ast.literal_eval(req.body) except SyntaxError: LOG.debug('invalid syntax %s', req.body) return Response(status=400) dpid = flow.get('dpid') dp = self.dpset.get(int(dpid)) if dp is None: return Response(status=404) if cmd == 'reset': cmd = dp.ofproto.OFPFC_MODIFY elif cmd == 'reset_strict': cmd = dp.ofproto.OFPFC_MODIFY_STRICT else: return Response(status=404) flow["flags"] = int(flow.get("flags", 0) | 4) if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.mod_flow_entry(dp, flow, cmd) elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: ofctl_v1_2.mod_flow_entry(dp, flow, cmd) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(dp, flow, cmd) else: LOG.debug('Unsupported OF protocol') return Response(status=501) return Response(status=200) else: return super(RestController, self).mod_flow_entry(req, cmd, **_kwargs)
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser mod_flow_entry(datapath, {}, ofproto.OFPFC_DELETE) priority = 100 self.logger.info('switch joind: datapath: %061x' % datapath.id) action = [] buckets = [] action.append(parser.OFPActionSetField(eth_src="00:00:00:00:00:00")) action.append(parser.OFPActionOutput(1, 0)) buckets.append(parser.OFPBucket(0,0,0,actions = action)) action = [] action.append(parser.OFPActionSetField(eth_src="00:00:00:00:00:01")) action.append(parser.OFPActionOutput(2, 0)) buckets.append(parser.OFPBucket(0,0,0,actions = action)) mod = parser.OFPGroupMod(datapath, ofproto.OFPGC_ADD, ofproto.OFPGT_ALL, 1, buckets) datapath.send_msg(mod) match = parser.OFPMatch(in_port = 1, eth_type = 0x800, ip_proto = socket.IPPROTO_UDP, udp_dst = 63) action = [] action.append(parser.OFPActionGroup(group_id = 1)) inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, action)] mod = parser.OFPFlowMod(datapath = datapath, priority = 100, match = match, instructions = inst) datapath.send_msg(mod)
def mod_flow_entry(self, req, cmd, **_kwargs): try: flow = eval(req.body) except SyntaxError: LOG.debug('invalid syntax %s', req.body) return Response(status=400) dpid = flow.get('dpid') dp = self.dpset.get(int(dpid)) if dp is None: return Response(status=404) if cmd == 'add': cmd = dp.ofproto.OFPFC_ADD elif cmd == 'modify': cmd = dp.ofproto.OFPFC_MODIFY elif cmd == 'delete': cmd = dp.ofproto.OFPFC_DELETE else: return Response(status=404) if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.mod_flow_entry(dp, flow, cmd) elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: ofctl_v1_2.mod_flow_entry(dp, flow, cmd) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(dp, flow, cmd) else: LOG.debug('Unsupported OF protocol') return Response(status=501) return Response(status=200)
def set_patch_flow(self, req_flow): # Check before send flow-mod dpid = req_flow.get("dpid") dp = self.dpset.get(dpid) if dp is None: return Response(status=400) inport = req_flow.get("inport") outport = req_flow.get("outport") mirrorport = req_flow.get("mirrorport") for flow in self.patch_flows: if dpid == flow["dpid"] and inport == flow["inport"]: LOG.info("Requested inport is already used (dpid:%s, inport:%d)", dpid, inport) return Response(status=400) new_flow = {"match": {"in_port": inport}, "actions": [{"type": "OUTPUT", "port": outport}]} if mirrorport is not None: new_flow["actions"].append({"type": "OUTPUT", "port": mirrorport}) if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.mod_flow_entry(dp, new_flow, dp.ofproto.OFPFC_ADD) self.patch_flows.append(req_flow) elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: ofctl_v1_2.mod_flow_entry(dp, new_flow, dp.ofproto.OFPFC_ADD) self.patch_flows.append(req_flow) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(dp, new_flow, dp.ofproto.OFPFC_ADD) self.patch_flows.append(req_flow) else: LOG.info("Unsupported OF protocol") return Response(status=501) return Response(status=200)
def delete_patch_flow(self, req_flow): # Check before send flow-mod dpid = req_flow.get('dpid') dp = self.dpset.get(dpid) if dp is None: return Response(status=400) inport = req_flow.get('inport') outport = req_flow.get('outport') mirrorport = req_flow.get('mirrorport') for flow in self.patch_flows: if dpid == flow['dpid'] and inport == flow['inport']: break else: LOG.info('Requested inport is not used (dpid:%s, inport:%d)', dpid, inport) return Response(status=400) del_flow = {'match': {'in_port': inport}} if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.mod_flow_entry(dp, del_flow, dp.ofproto.OFPFC_DELETE) self.patch_flows.remove(req_flow) elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: ofctl_v1_2.mod_flow_entry(dp, del_flow, dp.ofproto.OFPFC_DELETE) self.patch_flows.remove(req_flow) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(dp, del_flow, dp.ofproto.OFPFC_DELETE) self.patch_flows.remove(req_flow) else: LOG.debug('Unsupported OF protocol') return Response(status=501) return Response(status=200)
def mod_flow_entry(self, req, cmd, **_kwargs): try: flow = eval(req.body) except SyntaxError: LOG.debug('invalid syntax %s', req.body) return Response(status=400) dpid = flow.get('dpid') dp = self.dpset.get(int(dpid)) if dp is None: return Response(status=404) if cmd == 'add': cmd = dp.ofproto.OFPFC_ADD elif cmd == 'modify': cmd = dp.ofproto.OFPFC_MODIFY elif cmd == 'delete': cmd = dp.ofproto.OFPFC_DELETE else: return Response(status=404) if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.mod_flow_entry(dp, flow, cmd) if dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(dp, flow, cmd) else: LOG.debug('Unsupported OF protocol') return Response(status=501) return Response(status=200)
def delete_flow(self, dp, flows): if flows == "": return cmd = dp.ofproto.OFPFC_DELETE_STRICT for f in flows: flow = f mod_flow_entry(dp, flow, cmd) self.r = []
def set_flow(self, flow={}, e_type=0): dpid = dpid_lib.dpid_to_str(self.dp.id) try: ofctl_v1_3.mod_flow_entry(self.dp, flow, ofproto_v1_3.OFPFC_ADD) except: return
def _restore_rules(self, dp, rules): LOG.info("Restauration des règles de "+str(dp.id)+" en cours...") flows = filter(lambda rule: "buckets" not in rule, rules) groups = filter(lambda rule: "buckets" in rule, rules) for rule in groups: ofctl_v1_3.mod_group_entry(dp, rule, dp.ofproto.OFPGC_ADD) for rule in flows: ofctl_v1_3.mod_flow_entry(dp, rule, dp.ofproto.OFPFC_ADD) LOG.info("Restauration des règles de "+str(dp.id)+" terminé")
def _mod_patch_flow_entry(self, dp, flow_rule, command): if dp.ofproto.OFP_VERSION in self.OFP_VERSIONS: if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.mod_flow_entry(dp, flow_rule, command) elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: ofctl_v1_2.mod_flow_entry(dp, flow_rule, command) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(dp, flow_rule, command) return True else: msg = "Unsupported OFP version: %s" % dp.ofproto.OFP_VERSION raise patch_ofc_error.PatchOfcError(msg)
def _state_change_handler(self, ev): dp = ev.datapath if ev.state == MAIN_DISPATCHER: if not dp.id in self.datapaths: self.logger.debug('register datapath: %016x', dp.id) self.datapaths[dp.id] = datapath.IDSDatapath(dp, self) self.logger.debug('Removing all flows from dp: %016', dp.id) ofctl_v1_3.mod_flow_entry(dp, {}, dp.ofproto.OFPFC_DELETE) elif ev.state == DEAD_DISPATCHER: if dp.id in self.datapaths: self.logger.debug('unregister datapath: %016x', dp.id) del self.datapaths[dp.id]
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto mod_flow_entry(datapath, {}, ofproto.OFPFC_DELETE) priority = 100 self.logger.info('switch joind: datapath: %061x' % datapath.id) mod_flow_entry(datapath, {'priority' : priority, 'match' : {'in_port' : 1}, 'actions' : [{'type' : 'OUTPUT', 'port' : 2}]}, ofproto.OFPFC_ADD)
def delete_flow_entry(self, req, dpid, **_kwargs): dp = self.dpset.get(int(dpid)) if dp is None: return Response(status=404) if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.delete_flow_entry(dp) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(dp, {}, dp.ofproto.OFPFC_DELETE) else: LOG.debug('Unsupported OF protocol') return Response(status=501) return Response(status=200)
def initialize_switch(self): flow_stat = ofctl.get_flow_stats(self.dp, self.waiters) for s in flow_stat[str(self.dp.id)]: self.logger.debug("deleting flow [cookie: %d]" % s['cookie']) cmd = self.dp.ofproto.OFPFC_DELETE ofctl.mod_flow_entry(self.dp, {'table_id':self.dp.ofproto.OFPTT_ALL}, cmd) group_stat = ofctl.get_group_desc(self.dp, self.waiters) for s in group_stat[str(self.dp.id)]: self.logger.debug("deleting group[id: %d] %s" % (s['group_id'], s)) cmd = self.dp.ofproto.OFPGC_DELETE ofctl.mod_group_entry(self.dp, {'type':s['type'], 'group_id':s['group_id']}, cmd) ofctl.mod_meter_entry(self.dp, {'meter_id':self.dp.ofproto.OFPM_ALL}, self.dp.ofproto.OFPMC_DELETE)
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto mod_flow_entry(datapath, {}, ofproto.OFPFC_DELETE) # metadata = 123456789 # mod_flow_entry(datapath, # {'priority' : 100, # 'table_id' : 0, # 'cookie':0, # 'cookie_mask' :0, # 'match' : {'in_port' : 1}, # 'actions' : [{'type':'WRITE_METADATA', 'metadata':'123456789', 'metadata_mask':'5'}, # {'type':'GOTO_TABLE', 'table_id':1}]}, datapath.ofproto.OFPFC_ADD) # mod_flow_entry(datapath, # {'priority' : 100, # 'table_id' : 1, # 'cookie' : 0, # 'cookie_mask' : 0, # 'match' : {'metadata':'123456789/15'}, # 'actions' : [{'type' : 'OUTPUT', 'port' :2}]}, datapath.ofproto.OFPFC_ADD) ########## parser = datapath.ofproto_parser priority = 100 match = parser.OFPMatch() match.set_in_port(1) instructions = [parser.OFPInstructionWriteMetadata(123456789,15), parser.OFPInstructionGotoTable(1)] flow_mod = parser.OFPFlowMod(datapath = datapath, table_id=0, priority = priority, match=match, instructions=instructions) datapath.send_msg(flow_mod) ### output = parser.OFPActionOutput(2,0) output_to_controller = parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, 0) match = parser.OFPMatch() match.set_metadata_masked(0,1) actions = [output, output_to_controller] instructions = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] flow_mod = parser.OFPFlowMod(datapath = datapath, table_id=1, priority=priority, match=match, instructions=instructions) datapath.send_msg(flow_mod)
def topology_change_handler(self, ev): self.switches = get_switch(self) self.links = get_link(self) LOG.debug('\n\n\n') LOG.debug('show switches of topology') LOG.debug(self.switches) LOG.debug('\n\n\n') LOG.debug('show links of topology') links_json = json.dumps([link.to_dict() for link in self.links]) LOG.debug(links_json) LOG.debug('\n\n\n') LOG.debug('show switch_foo') switch_foo = Switch(self.switches.pop()) LOG.debug(switch_foo.dp) LOG.debug('\n\n\n') LOG.debug('show switch_foo.getDPID') LOG.debug(type(switch_foo.dp.getDPID())) switch_foo_dpid = switch_foo.dp.getDPID() LOG.debug(switch_foo_dpid) LOG.debug('\n\n\n') LOG.debug('show dpset') LOG.debug(self.dpset) LOG.debug('\n\n\n') flow = { 'table_id': 0, 'priority': 32768, 'match': { "ipv4_src": '10.0.0.1' #FIXME in ofctl_v1_3 is ipv4_src }, 'out_port': 1, 'actions': [ { "port": 1, "type": "OUTPUT" }, ], } cmds = { 'add': ofproto_v1_3.OFPFC_ADD, 'modif': ofproto_v1_3.OFPFC_MODIFY, 'del': ofproto_v1_3.OFPFC_DELETE, } ofctl_v1_3.mod_flow_entry(self.dpset[switch_foo_dpid], flow ,cmds['add']) LOG.debug("succefully execute the mod_flow_entry\n\n\n")
def packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser pkt = Packet(msg.data) pkt_udp = pkt.get_protocol(udp.udp) pkt_tcp = pkt.get_protocol(tcp.tcp) header_list = dict((p.protocol_name, p) for p in pkt.protocols if type(p) != str) self.logger.info(header_list) if pkt_udp: src_port = pkt_udp.src_port dst_port = pkt_udp.dst_port elif pkt_tcp: src_port = pkt_tcp.src_port dst_port = pkt_tcp.dst_port for ipproto in [6,17]: mod_flow_entry(datapath, {'priority' : 100, 'table_id' : 0, 'match' : {'tp_src': src_port, 'dl_type': 2048, 'ip_proto': ipproto}, 'actions' :[{'type': 'WRITE_METADATA', 'metadata': src_port << 16, 'metadata_mask' : 4294901760}, {'type': 'GOTO_TABLE', 'table_id' : 1}]}, ofproto.OFPFC_ADD) mod_flow_entry(datapath, {'priority' : 100, 'table_id' : 1, 'match' : {'tp_dst': dst_port, 'dl_type': 2048, 'ip_proto': ipproto}, 'actions' :[{'type': 'WRITE_METADATA', 'metadata': dst_port, 'metadata_mask': 65535}, {'type' : 'GOTO_TABLE', 'table_id' : 2}]}, ofproto.OFPFC_ADD) self.packet_out(datapath, pkt)
def delete_flow_entry(self, req, dpid, **_kwargs): dp = self.dpset.get(int(dpid)) if dp is None: return Response(status=404) if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.delete_flow_entry(dp) elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: ofctl_v1_2.mod_flow_entry(dp, {}, dp.ofproto.OFPFC_DELETE) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(dp, {}, dp.ofproto.OFPFC_DELETE) else: LOG.debug('Unsupported OF protocol') return Response(status=501) res = Response(status=200) res.headers.add('Access-Control-Allow-Origin', '*') return res
def mod_flow_entry(self, req, **kwargs): try: omniFlow = ast.literal_eval(req.body) #Getting flow from req except SyntaxError: LOG.debug('Invalid syntax %s', req.body) return Response(status=400) omniDpid = omniFlow.get('dpid') #Getting OmniUI dpid from flow if omniDpid is None: return Response(status=404) else: dpid = self.nospaceDPID( omniDpid.split(':')) #Split OmniUI dpid into a list cmd = omniFlow.get('command') #Getting OmniUI command from flow dp = self.dpset.get(int(dpid, 16)) #Getting datapath from Ryu dpid if dp is None: #NB: convert dpid to int first return Response(status=404) if cmd == 'ADD': cmd = dp.ofproto.OFPFC_ADD elif cmd == 'MOD': cmd = dp.ofproto.OFPFC_MODIFY elif cmd == 'MOD_ST': cmd = dp.ofproto.OFPFC_MODIFY_STRICT elif cmd == 'DEL': cmd = dp.ofproto.OFPFC_DELETE elif cmd == 'DEL_ST': cmd = dp.ofproto.OFPFC_DELETE_STRICT else: return Response(status=404) ryuFlow = {} if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ryuFlow = self.ryuFlow_v1_0(dp, omniFlow) ofctl_v1_0.mod_flow_entry(dp, ryuFlow, cmd) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ryuFlow = self.ryuFlow_v1_3(dp, omniFlow) ofctl_v1_3.mod_flow_entry(dp, ryuFlow, cmd) else: return Response(status=404) return Response(status=200)
def set_patch_flow(self, req_flow): # Check before send flow-mod dpid = req_flow.get('dpid') dp = self.dpset.get(dpid) if dp is None: return Response(status=400) inport = req_flow.get('inport') outport = req_flow.get('outport') mirrorport = req_flow.get('mirrorport') for flow in self.patch_flows: if dpid == flow['dpid'] and inport == flow['inport']: LOG.info( 'Requested inport is already used (dpid:%s, inport:%d)', dpid, inport) return Response(status=400) new_flow = { 'match': { 'in_port': inport }, 'actions': [{ 'type': 'OUTPUT', 'port': outport }] } if mirrorport is not None: new_flow['actions'].append({'type': 'OUTPUT', 'port': mirrorport}) if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ofctl_v1_0.mod_flow_entry(dp, new_flow, dp.ofproto.OFPFC_ADD) self.patch_flows.append(req_flow) elif dp.ofproto.OFP_VERSION == ofproto_v1_2.OFP_VERSION: ofctl_v1_2.mod_flow_entry(dp, new_flow, dp.ofproto.OFPFC_ADD) self.patch_flows.append(req_flow) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ofctl_v1_3.mod_flow_entry(dp, new_flow, dp.ofproto.OFPFC_ADD) self.patch_flows.append(req_flow) else: LOG.info('Unsupported OF protocol') return Response(status=501) return Response(status=200)
def initialize_switch(self): flow_stat = ofctl.get_flow_stats(self.dp, self.waiters) for s in flow_stat[str(self.dp.id)]: self.logger.debug("deleting flow [cookie: %d]" % s['cookie']) cmd = self.dp.ofproto.OFPFC_DELETE ofctl.mod_flow_entry(self.dp, {'table_id': self.dp.ofproto.OFPTT_ALL}, cmd) group_stat = ofctl.get_group_desc(self.dp, self.waiters) for s in group_stat[str(self.dp.id)]: self.logger.debug("deleting group[id: %d] %s" % (s['group_id'], s)) cmd = self.dp.ofproto.OFPGC_DELETE ofctl.mod_group_entry(self.dp, { 'type': s['type'], 'group_id': s['group_id'] }, cmd) ofctl.mod_meter_entry(self.dp, {'meter_id': self.dp.ofproto.OFPM_ALL}, self.dp.ofproto.OFPMC_DELETE)
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto mod_flow_entry(datapath, {}, ofproto.OFPFC_DELETE) priority = 100 self.logger.info('switch joind: datapath: %061x' % datapath.id) mod_flow_entry(datapath, {'priority' : priority, 'match' : {'in_port' : 1}, 'actions' : [{'type' : 'SET_FIELD', 'field': 'ipv4_dst', 'value': '20.0.0.2'}, {'type' : 'OUTPUT', 'port' :2}]}, ofproto.OFPFC_ADD) mod_flow_entry(datapath, {'priority' : priority, 'match' : {'in_port' : 2}, 'actions' : [{'type' : 'OUTPUT', 'port':1}]}, ofproto.OFPFC_ADD) time.sleep(10) mod_flow_entry(datapath, {'priority' : priority, 'match' : {'in_port' : 3}, 'actions' : [{'type' : 'OUTPUT', 'port':1}]}, ofproto.OFPFC_ADD) mod_flow_entry(datapath, {'priority' : priority, 'match' : {'in_port' : 1}, 'actions' : [{'type' : 'SET_FIELD', 'field': 'ipv4_dst', 'value': '20.0.0.2'}, {'type' : 'OUTPUT', 'port' :1}, {'type' : 'SET_FIELD', 'field': 'ipv4_dst', 'value': '30.0.0.2'}, {'type' : 'OUTPUT', 'port' :2}]}, ofproto.OFPFC_MODIFY_STRICT) datapath.send_barrier()
def mod_flow_entry(self, req, **kwargs): try: omniFlow = ast.literal_eval(req.body) #Getting flow from req except SyntaxError: LOG.debug('Invalid syntax %s', req.body) return Response(status=400) omniDpid = omniFlow.get('dpid') #Getting OmniUI dpid from flow if omniDpid is None: return Response(status=404) else: dpid = self.nospaceDPID(omniDpid.split(':')) #Split OmniUI dpid into a list cmd = omniFlow.get('command') #Getting OmniUI command from flow dp = self.dpset.get(int(dpid, 16)) #Getting datapath from Ryu dpid if dp is None: #NB: convert dpid to int first return Response(status=404) if cmd == 'ADD': cmd = dp.ofproto.OFPFC_ADD elif cmd == 'MOD': cmd = dp.ofproto.OFPFC_MODIFY elif cmd == 'MOD_ST': cmd = dp.ofproto.OFPFC_MODIFY_STRICT elif cmd == 'DEL': cmd = dp.ofproto.OFPFC_DELETE elif cmd == 'DEL_ST': cmd = dp.ofproto.OFPFC_DELETE_STRICT else: return Response(status=404) ryuFlow={} if dp.ofproto.OFP_VERSION == ofproto_v1_0.OFP_VERSION: ryuFlow = self.ryuFlow_v1_0(dp, omniFlow) ofctl_v1_0.mod_flow_entry(dp, ryuFlow, cmd) elif dp.ofproto.OFP_VERSION == ofproto_v1_3.OFP_VERSION: ryuFlow = self.ryuFlow_v1_3(dp, omniFlow) ofctl_v1_3.mod_flow_entry(dp, ryuFlow, cmd) else: return Response(status=404) return Response(status=200)
def _switch_enter_handler(self, ev): datapath = ev.switch.dp print('New switch is joined: %s' % datapath.id) flow = { 'match': { # Match any packets }, 'actions': [ { 'type': 'OUTPUT', 'port': ofproto_v1_3.OFPP_CONTROLLER, 'max_len': ofproto_v1_3.OFPCML_MAX, }, ] } ofctl_v1_3.mod_flow_entry( datapath, flow, ofproto_v1_3.OFPFC_ADD, )
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto self.logger.info('switch joind: datapath: %061x' % datapath.id) #initialize for var in range(0,3): mod_flow_entry(datapath, {'table_id' : var}, ofproto.OFPFC_DELETE) for var in range(0,2): for ipproto in [6,17]: mod_flow_entry(datapath, {'priority' : 1, 'table_id' : var, 'match' : {'dl_type' : 2048, 'ip_proto' : ipproto}, 'actions' :[{'type' : 'OUTPUT', 'port' : ofproto.OFPP_CONTROLLER}]}, ofproto.OFPFC_ADD) mod_flow_entry(datapath, {'priority' : 1, 'table_id' : var, 'match' : {}, 'actions' :[{'type' : 'GOTO_TABLE', 'table_id' : var+1}]}, ofproto.OFPFC_ADD) mod_flow_entry(datapath, {'priority' : 1, 'table_id' : 2, 'match' : {'in_port':1}, 'actions' :[{'type' : 'OUTPUT', 'port' :2}]}, ofproto.OFPFC_ADD) mod_flow_entry(datapath, {'priority' : 1, 'table_id' : 2, 'match' : {'in_port':2}, 'actions' :[{'type' : 'OUTPUT', 'port' :1}]}, ofproto.OFPFC_ADD) for k in self.flow_info.keys(): self.add_flow_rules(datapath, ofproto, self.flow_info[k])
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto mod_flow_entry(datapath, {}, ofproto.OFPFC_DELETE) priority = 100 self.logger.info('switch joind: datapath: %061x' % datapath.id) mod_flow_entry(datapath, {'priority' : priority, 'match' : {'in_port' : 1}, 'actions' : [{'type' : 'SET_FIELD', 'field': 'ipv4_dst', 'value': '172.16.0.1'}, {'type' : 'OUTPUT', 'port' : 2}, {'type' : 'SET_FIELD', 'field' : 'ipv4_dst', 'value' : '10.0.0.1'}, {'type' : 'OUTPUT', 'port' : 3}, {'type' : 'SET_FIELD', 'field': 'ipv4_dst', 'value' : '192.168.0.1'}, {'type' : 'OUTPUT', 'port' :2}]}, ofproto.OFPFC_ADD)
def add_flow_rules(self, datapath, ofproto, rule): print rule _src_ipaddr = netaddr.IPNetwork(rule["src_ipaddr"]) src_ip = str(_src_ipaddr) _dst_ipaddr = netaddr.IPNetwork(rule["dst_ipaddr"]) dst_ip = str(_dst_ipaddr) self.port_list_src = self.calculate_port_mask(rule["src_port_min"], rule["src_port_max"], 0) self.port_list_dst = self.calculate_port_mask(rule["dst_port_min"], rule["dst_port_max"], 0) for l in self.port_list_src: for m in self.port_list_dst: metadata = str((l['key'] << 16) + m['key']) metadata_mask = str((l['mask'] << 16) + m['mask']) mod_flow_entry(datapath, {'priority' : rule["priority"], 'table_id' : 2, 'match' : {'ipv4_src' : src_ip, 'ipv4_dst' : dst_ip, 'dl_type' : 2048, 'ip_proto' : int(rule["ipproto"]), 'metadata' : metadata + '/' + metadata_mask}, 'actions' : []}, ofproto.OFPFC_ADD)
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto self.logger.info('switch joind: datapath: %061x' % datapath.id) slg_id = datapath.id - 1 # base flow flow = {'priority': 1, 'table_id': 0} flow['match'] = {'in_port': 1} flow['actions'] = [{'type':'OUTPUT','port': 2}] print(flow) mod_flow_entry(datapath, flow, ofproto.OFPFC_ADD) flow['match'] = {'in_port': 2} flow['actions'] = [{'type':'OUTPUT','port': 1}] print(flow) mod_flow_entry(datapath, flow, ofproto.OFPFC_ADD) if slg_id != 1 : # in_port: 1 ENCAP flow = {'priority': 10, 'table_id':0} flow['match'] = {'in_port': 1, "dl_type":2048} flow['actions'] = make_vxlan_encap_action( eth_src = slg[slg_id].interface[2].mac_address, eth_dst = slg[slg_id].interface[2].gateway.mac_address, ipv4_src = slg[slg_id].interface[2].ip_address, ipv4_dst = slg[2 if slg_id != 2 else 0].interface[2].ip_address, udp_src = 12345, vni = 5000 + 4 * 10 ) flow['actions'].append({"type":"OUTPUT", "port": 2}) print(flow) mod_flow_entry(datapath, flow, ofproto.OFPFC_ADD) # in_port: 2 DECAP flow = {'priority': 10, 'table_id':0} flow['match'] = {'in_port':2, 'dl_type': 2048, "nw_proto":17, "tp_dst": 4789} flow['actions'] = make_vxlan_decap_action() flow['actions'].append({"type": "SET_FIELD", "field": "eth_dst", "value": slg[slg_id].interface[1].gateway.mac_address}) flow['actions'].append({"type":"OUTPUT", "port": 1}) print(flow) mod_flow_entry(datapath, flow, ofproto.OFPFC_ADD)
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto mod_flow_entry(datapath, {}, ofproto.OFPFC_DELETE) priority = 100 self.logger.info('switch joind: datapath: %061x' % datapath.id) mod_flow_entry(datapath, {'priority' : priority, 'cookie' : 1234605616436508552, 'cookie_mask': 0, 'match' : {'dl_type' : ETH_TYPE_IP, 'ipv4_dst' : '192.168.1.1'}, 'actions' : [{'type' : 'OUTPUT', 'port' : 2}]}, ofproto.OFPFC_ADD) self.logger.info("----flow mod----") time.sleep(10) self.logger.info("---flow delete---") mod_flow_entry(datapath, {'cookie':1234605616436508552}, ofproto.OFPFC_DELETE)
def _setup_dp(): self.dp = ev.dp # delete all flows and groups at first self.logger.debug("initializing..") self.initialize_switch() # create flood to down group entry buckets = [] for vid in (i + 101 for i in range(3)): actions = [{ 'type': 'PUSH_VLAN', 'ethertype': ether.ETH_TYPE_8021Q }, { 'type': 'SET_FIELD', 'field': 'vlan_vid', 'value': vid | 0x1000 }, { 'type': 'OUTPUT', 'port': self.inter_port }] buckets.append({'actions': actions}) buckets.append( {'actions': [{ 'type': 'OUTPUT', 'port': self.access_port }]}) buckets.append( {'actions': [{ 'type': 'OUTPUT', 'port': self.wlc_port }]}) self.flood_group_ids = [] for i in range(len(buckets)): group_id = self._next_cookie() self.flood_group_ids.append(group_id) b = [] for j, e in enumerate(buckets): if j != i: b.append(e) ofctl.mod_group_entry(self.dp, { 'type': 'ALL', 'group_id': group_id, 'buckets': b }, self.dp.ofproto.OFPGC_ADD) buckets = [] buckets.append( {'actions': [{ 'type': 'OUTPUT', 'port': self.access_port }]}) buckets.append( {'actions': [{ 'type': 'OUTPUT', 'port': self.wlc_port }]}) group_id = self._next_cookie() self.flood_group_ids.append(group_id) ofctl.mod_group_entry(self.dp, { 'type': 'ALL', 'group_id': group_id, 'buckets': buckets }, self.dp.ofproto.OFPGC_ADD) # create 3 meter entry meter_id = self._next_cookie() self.low_meter_id = meter_id meter = { 'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{ 'type': 'DROP', 'rate': 50000 }] } ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) meter_id = self._next_cookie() self.mid_meter_id = meter_id meter = { 'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{ 'type': 'DROP', 'rate': 30000 }] } ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) meter_id = self._next_cookie() self.high_meter_id = meter_id meter = { 'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{ 'type': 'DROP', 'rate': 20000 }] } ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) # default drop at table 0 cmd = self.dp.ofproto.OFPFC_ADD flow = { 'priority': 0, 'table_id': 0, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) # default flood up at table 1 cmd = self.dp.ofproto.OFPFC_ADD # match = {'in_port' : self.inter_port, 'metadata' : '101'} match = {'in_port': self.inter_port} actions = [{'type': 'GROUP', 'group_id': self.flood_group_ids[5]}] flow = { 'match': match, 'priority': 0, 'table_id': 1, 'actions': actions, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) ## match = {'in_port' : self.inter_port, 'metadata' : '102'} # match = {'in_port' : self.inter_port} # actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[1]}] # flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} # ofctl.mod_flow_entry(self.dp, flow, cmd) # ## match = {'in_port' : self.inter_port, 'metadata' : '103'} # match = {'in_port' : self.inter_port} # actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[2]}] # flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} # ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port': self.access_port} actions = [{'type': 'GROUP', 'group_id': self.flood_group_ids[3]}] flow = { 'match': match, 'priority': 0, 'table_id': 1, 'actions': actions, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port': self.wlc_port} actions = [{'type': 'GROUP', 'group_id': self.flood_group_ids[4]}] flow = { 'match': match, 'priority': 0, 'table_id': 1, 'actions': actions, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) # packet-in when node is not familier at table 0 actions = [{ 'type': 'OUTPUT', 'port': self.dp.ofproto.OFPP_CONTROLLER }] # should be more tight? may occur many packet in match = {'in_port': self.inter_port} flow = { 'match': match, 'actions': actions, 'table_id': 0, 'priority': 1, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port': self.access_port} flow = { 'match': match, 'actions': actions, 'table_id': 0, 'priority': 1, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port': self.wlc_port} flow = { 'match': match, 'actions': actions, 'table_id': 0, 'priority': 1, 'cookie': self._next_cookie() } ofctl.mod_flow_entry(self.dp, flow, cmd)
def packet_in_handler(self, ev): msg = ev.msg dp = msg.datapath ofproto = dp.ofproto parser = dp.ofproto_parser try: pkt = packet.Packet(msg.data) except: self.logger.debug("malformed packet") return header_list = dict((p.protocol_name, p) for p in pkt.protocols if type(p) != str) self.logger.debug(header_list) cmd = self.dp.ofproto.OFPFC_DELETE dl_mac = header_list['ethernet'].src ofctl.mod_flow_entry(self.dp, {'table_id':0, 'match':{'dl_src':dl_mac}}, cmd) ofctl.mod_flow_entry(self.dp, {'table_id':1, 'match':{'dl_dst':dl_mac}}, cmd) cmd = self.dp.ofproto.OFPFC_ADD if 'vlan' in header_list: match = {'dl_vlan':header_list['vlan'].vid, 'dl_src':dl_mac} actions = [{'type':'POP_VLAN'}, # {'type':'WRITE_METADATA', 'metadata':str(header_list['vlan'].vid)}, {'type':'GOTO_TABLE', 'table_id':1}] else: match = {'dl_src':dl_mac} actions = [{'type':'GOTO_TABLE', 'table_id':1}] flow = {'match':match, 'actions':actions, 'table_id':0, 'idle_timeout':60, 'cookie':self._next_cookie(), 'priority':20} ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'dl_dst':dl_mac} actions = [] if msg.match['in_port'] == self.inter_port: if 'vlan' in header_list: vid = header_list['vlan'].vid else: self.logger.debug("come from trunk port, but have no vlan header") return if vid == 101: self.logger.debug("add low meter flow") actions.append({'type':'METER', 'meter_id':self.low_meter_id}) elif vid == 102: self.logger.debug("add mid meter flow") actions.append({'type':'METER', 'meter_id':self.mid_meter_id}) elif vid == 103: self.logger.debug("add high meter flow") actions.append({'type':'METER', 'meter_id':self.high_meter_id}) else: self.logger.debug("invalid vlan id: %d" % vid) return actions.append({'type':'PUSH_VLAN', 'ethertype': ether.ETH_TYPE_8021Q}) actions.append({'type':'SET_FIELD', 'field':'vlan_vid', 'value':vid | 0x1000}) actions.append({'type':'OUTPUT', 'port':msg.match['in_port']}) flow = {'match':match, 'actions':actions, 'table_id':1, 'idle_timeout':60, 'cookie':self._next_cookie(), 'priority':20} ofctl.mod_flow_entry(self.dp, flow, cmd) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data if 'vlan' in header_list: vid = header_list['vlan'].vid self.logger.debug(pkt.protocols) v = pkt.protocols.pop(1) self.logger.debug("VLAN: %s" % v) e = pkt.protocols[0] e.ethertype = v.ethertype self.logger.debug(pkt.protocols) self.logger.debug("going to serialize") data = pkt.serialize() if vid == 101: group_id = self.flood_group_ids[0] elif vid == 102: group_id = self.flood_group_ids[1] elif vid == 103: group_id = self.flood_group_ids[2] else: self.logger.debug("invalid vlan id: %d" % vid) return group_id = self.flood_group_ids[5] out = parser.OFPPacketOut(datapath=dp, buffer_id=ofproto.OFP_NO_BUFFER, in_port=msg.match['in_port'], actions=[parser.OFPActionGroup(group_id)], data=data) else: if msg.match['in_port'] == self.access_port: group_id = self.flood_group_ids[3] elif msg.match['in_port'] == self.wlc_port: group_id = self.flood_group_ids[4] else: self.logger.debug("invalid in_port: %d" % msg.match['in_port']) return out = parser.OFPPacketOut(datapath=dp, buffer_id=msg.buffer_id, in_port=msg.match['in_port'], actions=[parser.OFPActionGroup(group_id)], data=data) dp.send_msg(out)
def _setup_dp(): self.dp = ev.dp # delete all flows and groups at first self.logger.debug("initializing..") self.initialize_switch() # create flood to down group entry buckets = [] for vid in (i+101 for i in range(3)): actions = [{'type':'PUSH_VLAN', 'ethertype':ether.ETH_TYPE_8021Q}, {'type':'SET_FIELD', 'field':'vlan_vid', 'value':vid | 0x1000}, {'type':'OUTPUT', 'port':self.inter_port}] buckets.append({'actions': actions}) buckets.append({'actions':[{'type':'OUTPUT', 'port':self.access_port}]}) buckets.append({'actions':[{'type':'OUTPUT', 'port':self.wlc_port}]}) self.flood_group_ids = [] for i in range(len(buckets)): group_id = self._next_cookie() self.flood_group_ids.append(group_id) b = [] for j, e in enumerate(buckets): if j != i: b.append(e) ofctl.mod_group_entry(self.dp, {'type':'ALL', 'group_id':group_id, 'buckets':b}, self.dp.ofproto.OFPGC_ADD) buckets = [] buckets.append({'actions':[{'type':'OUTPUT', 'port':self.access_port}]}) buckets.append({'actions':[{'type':'OUTPUT', 'port':self.wlc_port}]}) group_id = self._next_cookie() self.flood_group_ids.append(group_id) ofctl.mod_group_entry(self.dp, {'type':'ALL', 'group_id':group_id, 'buckets':buckets}, self.dp.ofproto.OFPGC_ADD) # create 3 meter entry meter_id = self._next_cookie() self.low_meter_id = meter_id meter = {'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{'type': 'DROP', 'rate': 50000}]} ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) meter_id = self._next_cookie() self.mid_meter_id = meter_id meter = {'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{'type': 'DROP', 'rate': 30000}]} ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) meter_id = self._next_cookie() self.high_meter_id = meter_id meter = {'meter_id': meter_id, 'flags': 'KBPS', 'bands': [{'type': 'DROP', 'rate': 20000}]} ofctl.mod_meter_entry(self.dp, meter, self.dp.ofproto.OFPMC_ADD) # default drop at table 0 cmd = self.dp.ofproto.OFPFC_ADD flow = {'priority':0, 'table_id':0, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) # default flood up at table 1 cmd = self.dp.ofproto.OFPFC_ADD # match = {'in_port' : self.inter_port, 'metadata' : '101'} match = {'in_port' : self.inter_port} actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[5]}] flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) ## match = {'in_port' : self.inter_port, 'metadata' : '102'} # match = {'in_port' : self.inter_port} # actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[1]}] # flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} # ofctl.mod_flow_entry(self.dp, flow, cmd) # ## match = {'in_port' : self.inter_port, 'metadata' : '103'} # match = {'in_port' : self.inter_port} # actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[2]}] # flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} # ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port' : self.access_port} actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[3]}] flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port' : self.wlc_port} actions = [{'type':'GROUP', 'group_id':self.flood_group_ids[4]}] flow = {'match':match, 'priority':0, 'table_id':1, 'actions':actions, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) # packet-in when node is not familier at table 0 actions = [{'type':'OUTPUT', 'port':self.dp.ofproto.OFPP_CONTROLLER}] # should be more tight? may occur many packet in match = {'in_port' : self.inter_port} flow = {'match':match, 'actions':actions, 'table_id':0, 'priority':1, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port' : self.access_port} flow = {'match':match, 'actions':actions, 'table_id':0, 'priority':1, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'in_port' : self.wlc_port} flow = {'match':match, 'actions':actions, 'table_id':0, 'priority':1, 'cookie':self._next_cookie()} ofctl.mod_flow_entry(self.dp, flow, cmd)
def set_tcp_port(self, ip_src, ip_dst, tcp1, tcp2, vlan_src, vlan_dst, inport, outport, mode): flows = [] if mode == 'add': cmd = self.dp.ofproto.OFPFC_ADD elif mode == 'delete': cmd = self.dp.ofproto.OFPFC_DELETE_STRICT match = { "in_port": inport, "dl_vlan": int(vlan_src), "ip_proto": 6, "tcp_dst": int(tcp1), "ipv4_src": ip_src, "ipv4_dst": ip_dst, "eth_type": 2048 } actions = [{ "type": "POP_VLAN", "ethertype": 33024 }, { "type": "PUSH_VLAN", "ethertype": 33024 }, { "type": "SET_FIELD", "field": "vlan_vid", "value": 4096 + int(vlan_dst) }, { "type": "SET_FIELD", "field": "tcp_dst", "value": int(tcp2) }, { "type": "OUTPUT", "port": outport }] flow = self._to_of_flow(priority=1000, match=match, actions=actions) flows.append(flow) try: ofctl_v1_3.mod_flow_entry(self.dp, flow, cmd) except: raise ValueError('Invalid rule parameter.') match = { "in_port": outport, "dl_vlan": int(vlan_dst), "ipv4_src": ip_dst, "ip_proto": 6, "tcp_src": int(tcp2), "ipv4_dst": ip_src, "eth_type": 2048 } actions = [{ "type": "POP_VLAN", "ethertype": 33024 }, { "type": "PUSH_VLAN", "ethertype": 33024 }, { "type": "SET_FIELD", "field": "vlan_vid", "value": 4096 + int(vlan_src) }, { "type": "SET_FIELD", "field": "tcp_src", "value": int(tcp1) }, { "type": "OUTPUT", "port": inport }] flow = self._to_of_flow(priority=1000, match=match, actions=actions) flows.append(flow) try: ofctl_v1_3.mod_flow_entry(self.dp, flow, cmd) except: raise ValueError('Invalid rule parameter.') msg = json.dumps({'result': 'Rules added!'}) return Response(content_type='application/json', body=msg)
def packet_in_handler(self, ev): msg = ev.msg dp = msg.datapath ofproto = dp.ofproto parser = dp.ofproto_parser try: pkt = packet.Packet(msg.data) except: self.logger.debug("malformed packet") return header_list = dict( (p.protocol_name, p) for p in pkt.protocols if type(p) != str) self.logger.debug(header_list) cmd = self.dp.ofproto.OFPFC_DELETE dl_mac = header_list['ethernet'].src ofctl.mod_flow_entry(self.dp, { 'table_id': 0, 'match': { 'dl_src': dl_mac } }, cmd) ofctl.mod_flow_entry(self.dp, { 'table_id': 1, 'match': { 'dl_dst': dl_mac } }, cmd) cmd = self.dp.ofproto.OFPFC_ADD if 'vlan' in header_list: match = {'dl_vlan': header_list['vlan'].vid, 'dl_src': dl_mac} actions = [ { 'type': 'POP_VLAN' }, # {'type':'WRITE_METADATA', 'metadata':str(header_list['vlan'].vid)}, { 'type': 'GOTO_TABLE', 'table_id': 1 } ] else: match = {'dl_src': dl_mac} actions = [{'type': 'GOTO_TABLE', 'table_id': 1}] flow = { 'match': match, 'actions': actions, 'table_id': 0, 'idle_timeout': 60, 'cookie': self._next_cookie(), 'priority': 20 } ofctl.mod_flow_entry(self.dp, flow, cmd) match = {'dl_dst': dl_mac} actions = [] if msg.match['in_port'] == self.inter_port: if 'vlan' in header_list: vid = header_list['vlan'].vid else: self.logger.debug( "come from trunk port, but have no vlan header") return if vid == 101: self.logger.debug("add low meter flow") actions.append({ 'type': 'METER', 'meter_id': self.low_meter_id }) elif vid == 102: self.logger.debug("add mid meter flow") actions.append({ 'type': 'METER', 'meter_id': self.mid_meter_id }) elif vid == 103: self.logger.debug("add high meter flow") actions.append({ 'type': 'METER', 'meter_id': self.high_meter_id }) else: self.logger.debug("invalid vlan id: %d" % vid) return actions.append({ 'type': 'PUSH_VLAN', 'ethertype': ether.ETH_TYPE_8021Q }) actions.append({ 'type': 'SET_FIELD', 'field': 'vlan_vid', 'value': vid | 0x1000 }) actions.append({'type': 'OUTPUT', 'port': msg.match['in_port']}) flow = { 'match': match, 'actions': actions, 'table_id': 1, 'idle_timeout': 60, 'cookie': self._next_cookie(), 'priority': 20 } ofctl.mod_flow_entry(self.dp, flow, cmd) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data if 'vlan' in header_list: vid = header_list['vlan'].vid self.logger.debug(pkt.protocols) v = pkt.protocols.pop(1) self.logger.debug("VLAN: %s" % v) e = pkt.protocols[0] e.ethertype = v.ethertype self.logger.debug(pkt.protocols) self.logger.debug("going to serialize") data = pkt.serialize() if vid == 101: group_id = self.flood_group_ids[0] elif vid == 102: group_id = self.flood_group_ids[1] elif vid == 103: group_id = self.flood_group_ids[2] else: self.logger.debug("invalid vlan id: %d" % vid) return group_id = self.flood_group_ids[5] out = parser.OFPPacketOut( datapath=dp, buffer_id=ofproto.OFP_NO_BUFFER, in_port=msg.match['in_port'], actions=[parser.OFPActionGroup(group_id)], data=data) else: if msg.match['in_port'] == self.access_port: group_id = self.flood_group_ids[3] elif msg.match['in_port'] == self.wlc_port: group_id = self.flood_group_ids[4] else: self.logger.debug("invalid in_port: %d" % msg.match['in_port']) return out = parser.OFPPacketOut( datapath=dp, buffer_id=msg.buffer_id, in_port=msg.match['in_port'], actions=[parser.OFPActionGroup(group_id)], data=data) dp.send_msg(out)
def set_flows(self, dp, f): self.delete_flow(dp, self.r) flow = { "priority": 1000, "match": { "eth_type": 2048, "ip_proto": 6, "in_port": int(f["iport"]), "ipv4_dst": self.dst['nw'], "tcp_dst": self.dst['tp'] }, "actions": [{ "type": "SET_FIELD", "field": "ipv4_dst", "value": f["nw"] }, { "type": "SET_FIELD", "field": "tcp_dst", "value": int(f["tp"]) }, { "type": "SET_FIELD", "field": "eth_dst", "value": f["dl"] }, { "type": "OUTPUT", "port": int(f["oport"]) }] } try: mod_flow_entry(dp, flow, dp.ofproto.OFPFC_ADD) except: raise ValueError('Invalid rule parameter.') self.r.append(flow) flow = { "priority": 1000, "match": { "eth_type": 2048, "ip_proto": 6, "in_port": int(f["oport"]), "ipv4_src": f["nw"], "tcp_src": f["tp"] }, "actions": [{ "type": "SET_FIELD", "field": "ipv4_src", "value": self.dst['nw'] }, { "type": "SET_FIELD", "field": "tcp_src", "value": int(self.dst['tp']) }, { "type": "SET_FIELD", "field": "eth_src", "value": self.dst["dl"] }, { "type": "OUTPUT", "port": int(f["iport"]) }] } try: mod_flow_entry(dp, flow, dp.ofproto.OFPFC_ADD) except: raise ValueError('Invalid rule parameter.') self.r.append(flow)
def delete_flow(self, flow={}, e_num=0): dpid = dpid_lib.dpid_to_str(self.dp.id) ofctl_v1_3.mod_flow_entry(self.dp, flow, ofproto_v1_3.OFPFC_DELETE)
def set_rule(self, ip_src, ip_dst, vlan_src, vlan_dst, inport, outport, mode): flows = [] if mode == 'add': cmd = self.dp.ofproto.OFPFC_ADD elif mode == 'delete': cmd = self.dp.ofproto.OFPFC_DELETE_STRICT if vlan_src > 0: match = { "in_port": inport, "dl_vlan": int(vlan_src), "ipv4_src": ip_src, "ipv4_dst": ip_dst, "eth_type": 2048 } else: match = { "in_port": inport, "ipv4_src": ip_src, "ipv4_dst": ip_dst, "eth_type": 2048 } if vlan_dst > 0: actions = [{ "type": "POP_VLAN", "ethertype": 33024 }, { "type": "PUSH_VLAN", "ethertype": 33024 }, { "type": "SET_FIELD", "field": "vlan_vid", "value": 4096 + int(vlan_dst) }, { "type": "OUTPUT", "port": outport }] else: if vlan_src != vlan_dst: actions = [{ "type": "SET_FIELD", "field": "vlan_vid", "value": 4096 + int(vlan_dst) }, { "type": "OUTPUT", "port": outport }] else: actions = [{"type": "OUTPUT", "port": outport}] flow = self._to_of_flow(priority=1000, match=match, actions=actions) flows.append(flow) try: ofctl_v1_3.mod_flow_entry(self.dp, flow, cmd) except: raise ValueError('Invalid rule parameter.') if vlan_src > 0: match = { "in_port": inport, "dl_vlan": int(vlan_src), "arp_spa": ip_src, "arp_tpa": ip_dst, "eth_type": 2054 } else: match = { "in_port": inport, "arp_spa": ip_src, "arp_tpa": ip_dst, "eth_type": 2054 } if vlan_dst > 0: actions = [{ "type": "POP_VLAN", "ethertype": 33024 }, { "type": "PUSH_VLAN", "ethertype": 33024 }, { "type": "SET_FIELD", "field": "vlan_vid", "value": 4096 + int(vlan_dst) }, { "type": "OUTPUT", "port": outport }] else: if vlan_src != vlan_dst: actions = [{ "type": "SET_FIELD", "field": "vlan_vid", "value": 4096 + int(vlan_dst) }, { "type": "OUTPUT", "port": outport }] else: actions = [{"type": "OUTPUT", "port": outport}] flow = self._to_of_flow(priority=1000, match=match, actions=actions) flows.append(flow) try: self.ofctl.mod_flow_entry(self.dp, flow, cmd) except: raise ValueError('Invalid rule parameter.') if vlan_src > 0: match = { "in_port": outport, "dl_vlan": int(vlan_src), "ipv4_dst": ip_src, "ipv4_src": ip_dst, "eth_type": 2048 } else: match = { "in_port": outport, "ipv4_dst": ip_src, "ipv4_src": ip_dst, "eth_type": 2048 } actions = [{"type": "OUTPUT", "port": inport}] flow = self._to_of_flow(priority=1000, match=match, actions=actions) flows.append(flow) try: self.ofctl.mod_flow_entry(self.dp, flow, cmd) except: raise ValueError('Invalid rule parameter.') if vlan_src > 0: match = { "in_port": outport, "dl_vlan": int(vlan_src), "arp_tpa": ip_src, "arp_spa": ip_dst, "eth_type": 2054 } else: match = { "in_port": outport, "arp_tpa": ip_src, "arp_spa": ip_dst, "eth_type": 2054 } actions = [{"type": "OUTPUT", "port": inport}] flow = self._to_of_flow(priority=1000, match=match, actions=actions) flows.append(flow) try: self.ofctl.mod_flow_entry(self.dp, flow, cmd) except: raise ValueError('Invalid rule parameter.') msg = {'result': 'success'} return msg