def port_add_acl(self, port_num): ofmsgs = [] forwarding_table = self.dp.eth_src_table if port_num in self.dp.acl_in: acl_num = self.dp.acl_in[port_num] forwarding_table = self.dp.acl_table acl_rule_priority = self.dp.highest_priority acl_allow_inst = self.goto_table(self.dp.eth_src_table) for rule_conf in self.dp.acls[acl_num]: # default drop acl_inst = [] match_dict = {} for attrib, attrib_value in rule_conf.iteritems(): if attrib == 'allow': if attrib_value == 1: acl_inst.append(acl_allow_inst) continue if attrib == 'in_port': continue match_dict[attrib] = attrib_value # override in_port always match_dict['in_port'] = port_num # to_match() needs to access parser via dp # this uses the old API, which is oh so convenient # (transparently handling masks for example). null_dp = namedtuple('null_dp', 'ofproto_parser') null_dp.ofproto_parser = parser acl_match = ofctl.to_match(null_dp, match_dict) ofmsgs.append(self.valve_flowmod( self.dp.acl_table, acl_match, priority=acl_rule_priority, inst=acl_inst)) acl_rule_priority -= 1 return ofmsgs, forwarding_table
def handler_datapath(self, ev): dp = ev.dp ofproto = dp.ofproto parser = dp.ofproto_parser if ev.enter: self.logger.info("MARI => Switch connected:%s", dp.id) else: self.logger.info("MARI => Switch disconnected:%s", dp.id) return self.logger.info("Configuring datapath") # clear flow table on datapath self.clear_flows(dp, self.cookie) # add catchall drop rule to datapath drop_act = [] aclmatch = {} aclmatch['eth_type'] = 0x0800 match = ofctl_v1_3.to_match(dp, aclmatch) self.add_flow(dp, match, drop_act, 10000, self.cookie) self.logger.info("Configured match") self.logger.info("Datapath configured")
def create_firewall(self, filter_data): LOG.debug("Creating tap with filter = %s", str(filter_data)) dpid = filter_data['dpid'] if 'priority' in filter_data: priority = filter_data['priority'] else: priority = 32768 datapath = self.dpset.get(int(dpid, 16)) if datapath is None: LOG.debug("Unable to get datapath for id = %s", str(source['dpid'])) return False ofproto = datapath.ofproto ofproto_parser = datapath.ofproto_parser ######## Create match match = ofctl_v1_3.to_match(datapath, filter_data['fields']) ######## Cookie might come handy cookie = 0x2222222222222222 ######## init inst actions = [] inst = [] if 'normal' in filter_data['actions']: actions.append( ofproto_parser.OFPActionOutput(ofproto.OFPP_NORMAL, 0)) if 'drop' in filter_data['actions']: actions = [] inst.append( ofproto_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, priority=priority, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod)
def delete_tap(self, filter_data): LOG.debug("Deleting tap with filter %s", str(filter_data)) # If dl_host, nw_host or tp_port are used, the recursively call the individual filters. # This causes the match to expand and more rules to be programmed. filter_data.setdefault('fields', {}) filter_fields = filter_data['fields'] for key, val in self.broadened_field.iteritems(): if key in filter_fields: for new_val in val: filter_data['fields'] = self.change_field(filter_fields, key, new_val) self.delete_tap(filter_data) return # If match fields are exact, then proceed programming switches for source in filter_data['sources']: in_port = source['port_no'] filter_fields = filter_data['fields'].copy() if in_port != 'all': # If not sniffing on all in_ports filter_fields['in_port'] = in_port datapath = self.dpset.get(source['dpid']) # If dpid is invalid, return if datapath is None: continue ofproto = datapath.ofproto ofproto_parser = datapath.ofproto_parser match = ofctl_v1_3.to_match(datapath, filter_fields) mod = ofproto_parser.OFPFlowMod(datapath=datapath, command=ofproto.OFPFC_DELETE, match = match, out_port=ofproto.OFPP_ANY,out_group=ofproto.OFPG_ANY) datapath.send_msg(mod)
def handler_datapath(self, ev): dp = ev.dp ofproto = dp.ofproto parser = dp.ofproto_parser # Configure logging to include datapath id self.set_dpid_log_formatter(dp.id) if not ev.enter: # Datapath down message self.logger.info("Datapath gone away") self.set_default_log_formatter() return if dp.id not in self.dps: self.logger.error("Unknown dpid:%s", dp.id) self.set_default_log_formatter() return else: datapath = self.dps[dp.id] for k, port in dp.ports.items(): # These are special port numbers if k > 0xF0000000: continue elif k not in datapath.ports: # Autoconfigure port self.logger.info( "Autoconfiguring port:%s based on default config", k) datapath.add_port(k) self.logger.info("Configuring datapath") # clear flow table on datapath self.clear_flows(dp, datapath.config_default['cookie']) # add catchall drop rule to datapath drop_act = [] if datapath.config_default['table_miss']: match_all = parser.OFPMatch() priority = datapath.config_default['lowest_priority'] cookie = datapath.config_default['cookie'] self.add_flow(dp, match_all, drop_act, priority, cookie) for vid, v in datapath.vlans.items(): self.logger.info("Configuring %s", v) controller_act = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER)] # generate the output actions for each port tagged_act = self.tagged_output_action(parser, v.tagged) untagged_act = self.untagged_output_action(parser, v.untagged) # send rule for matching packets arriving on tagged ports strip_act = [parser.OFPActionPopVlan()] action = copy.copy(controller_act) if tagged_act: action += tagged_act if untagged_act: action += strip_act + untagged_act match = parser.OFPMatch(vlan_vid=v.vid | ofproto_v1_3.OFPVID_PRESENT) priority = datapath.config_default['low_priority'] cookie = datapath.config_default['cookie'] self.add_flow(dp, match, action, priority, cookie) # send rule for each untagged port push_act = [ parser.OFPActionPushVlan(ether.ETH_TYPE_8021Q), parser.OFPActionSetField(vlan_vid=v.vid | ofproto_v1_3.OFPVID_PRESENT) ] for port in v.untagged: match = parser.OFPMatch(in_port=port.number) action = copy.copy(controller_act) if untagged_act: action += untagged_act if tagged_act: action += push_act + tagged_act priority = datapath.config_default['low_priority'] cookie = datapath.config_default['cookie'] self.add_flow(dp, match, action, priority, cookie) for nw_address, acls in datapath.acls.items(): for acl in acls: if acl.action.lower() == "drop": self.logger.info("Adding ACL:{%s} for nw_address:%s", acl, nw_address) # Hacky method of detecting IPv4/IPv6 try: socket.inet_aton(nw_address.split('/')[0]) acl.match['nw_dst'] = nw_address except socket.error: acl.match['ipv6_dst'] = nw_address match = ofctl_v1_3.to_match(dp, acl.match) priority = datapath.config_default['highest_priority'] cookie = datapath.config_default['cookie'] self.add_flow(dp, match, drop_act, priority, cookie) for k, port in datapath.ports.items(): for acl in port.acls: if acl.action.lower() == "drop": self.logger.info("Adding ACL:{%s} to port:%s", acl, port) acl.match['in_port'] = port.number match = ofctl_v1_3.to_match(dp, acl.match) priority = datapath.config_default['highest_priority'] cookie = datapath.config_default['cookie'] self.add_flow(dp, match, drop_act, priority, cookie) # Mark datapath as fully configured datapath.running = True self.logger.info("Datapath configured") self.set_default_log_formatter()
def match_from_dict(match_dict): null_dp = namedtuple('null_dp', 'ofproto_parser') null_dp.ofproto_parser = parser acl_match = ofctl.to_match(null_dp, match_dict) return acl_match
def handler_datapath(self, ev): dp = ev.dp ofproto = dp.ofproto parser = dp.ofproto_parser # Configure logging to include datapath id self.set_dpid_log_formatter(dp.id) if not ev.enter: # Datapath down message self.logger.info("Datapath gone away") self.set_default_log_formatter() return if dp.id not in self.dps: self.logger.error("Unknown dpid:%s", dp.id) self.set_default_log_formatter() return else: datapath = self.dps[dp.id] for k, port in dp.ports.items(): # These are special port numbers if k > 0xF0000000: continue elif k not in datapath.ports: # Autoconfigure port self.logger.info("Autoconfiguring port:%s based on default config", k) datapath.add_port(k) self.logger.info("Configuring datapath") # clear flow table on datapath self.clear_flows(dp, datapath.config_default['cookie']) # add catchall drop rule to datapath drop_act = [] if datapath.config_default['table_miss']: match_all = parser.OFPMatch() priority = datapath.config_default['lowest_priority'] cookie = datapath.config_default['cookie'] self.add_flow(dp, match_all, drop_act, priority, cookie) for vid, v in datapath.vlans.items(): self.logger.info("Configuring %s", v) controller_act = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER)] # generate the output actions for each port tagged_act = self.tagged_output_action(parser, v.tagged) untagged_act = self.untagged_output_action(parser, v.untagged) # send rule for matching packets arriving on tagged ports strip_act = [parser.OFPActionPopVlan()] action = copy.copy(controller_act) if tagged_act: action += tagged_act if untagged_act: action += strip_act + untagged_act match = parser.OFPMatch(vlan_vid=v.vid|ofproto_v1_3.OFPVID_PRESENT) priority = datapath.config_default['low_priority'] cookie = datapath.config_default['cookie'] self.add_flow(dp, match, action, priority, cookie) # send rule for each untagged port push_act = [ parser.OFPActionPushVlan(ether.ETH_TYPE_8021Q), parser.OFPActionSetField(vlan_vid=v.vid|ofproto_v1_3.OFPVID_PRESENT) ] for port in v.untagged: match = parser.OFPMatch(in_port=port.number) action = copy.copy(controller_act) if untagged_act: action += untagged_act if tagged_act: action += push_act + tagged_act priority = datapath.config_default['low_priority'] cookie = datapath.config_default['cookie'] self.add_flow(dp, match, action, priority, cookie) for nw_address, acls in datapath.acls.items(): for acl in acls: if acl.action.lower() == "drop": self.logger.info("Adding ACL:{%s} for nw_address:%s", acl, nw_address) # Hacky method of detecting IPv4/IPv6 try: socket.inet_aton(nw_address.split('/')[0]) acl.match['nw_dst'] = nw_address except socket.error: acl.match['ipv6_dst'] = nw_address match = ofctl_v1_3.to_match(dp, acl.match) priority = datapath.config_default['highest_priority'] cookie = datapath.config_default['cookie'] self.add_flow(dp, match, drop_act, priority, cookie) for k, port in datapath.ports.items(): for acl in port.acls: if acl.action.lower() == "drop": self.logger.info("Adding ACL:{%s} to port:%s", acl, port) acl.match['in_port'] = port.number match = ofctl_v1_3.to_match(dp, acl.match) priority = datapath.config_default['highest_priority'] cookie = datapath.config_default['cookie'] self.add_flow(dp, match, drop_act, priority, cookie) # Mark datapath as fully configured datapath.running = True self.logger.info("Datapath configured") self.set_default_log_formatter()
def start_security(self, dpid): datapath = self.dpset.get(int(dpid, 16)) if datapath is None: LOG.debug("Unable to get datapath for id = %s", str(source['dpid'])) return False ofproto = datapath.ofproto ofproto_parser = datapath.ofproto_parser ######## Cookie might come handy cookie = 0x333333333333333 ######## init inst actions = [ofproto_parser.OFPActionOutput(ofproto.OFPP_NORMAL, 0)] inst = [ ofproto_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions) ] ######## Create tcp syc udf match & send flow tcp_match = {} tcp_match['udf0'] = '0x60000/0xff0000' tcp_match['udf2'] = '0x20000/0xfff0000' match = ofctl_v1_3.to_match(datapath, tcp_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) ######## Create dns query udf match & send flow dns_match = {} dns_match['udf0'] = '0x110000/0xff0000' dns_match['udf1'] = '0x00000035/0x0000ffff' match = ofctl_v1_3.to_match(datapath, dns_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) ######## Create http udf match & send flow http_match = {} http_match['udf0'] = '0x60000/0xff0000' http_match['udf1'] = '0x00000050/0x0000ffff' http_match['udf3'] = '0x47455400/0xffffff00' match = ofctl_v1_3.to_match(datapath, http_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) ######## Create icmp udf match & send flow icmp_match = {} icmp_match['udf0'] = '0x10000/0xff0000' match = ofctl_v1_3.to_match(datapath, icmp_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) ######## Create ntp attack udf match & send flow ntp_match = {} ntp_match['udf0'] = '0x110000/0xff0000' ntp_match['udf1'] = '0x0000607B/0x0000ffff' match = ofctl_v1_3.to_match(datapath, ntp_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) ######## Create udp/tcp udf match & send flow (2 flows) udp_tcp_match = {} udp_tcp_match['udf0'] = '0x110000/0xff0000' match = ofctl_v1_3.to_match(datapath, udp_tcp_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, priority=1000, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) udp_tcp_match = {} udp_tcp_match['udf0'] = '0x60000/0xff0000' match = ofctl_v1_3.to_match(datapath, udp_tcp_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, priority=1000, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod)
def create_tap(self, filter_data): LOG.debug("Creating tap with filter = %s", str(filter_data)) # If dl_host, nw_host or tp_port are used, the recursively call the individual filters. # This causes the match to expand and more rules to be programmed. result = True filter_data.setdefault('fields', {}) filter_fields = filter_data['fields'] for key, val in self.broadened_field.iteritems(): if key in filter_fields: for new_val in val: filter_data['fields'] = self.change_field( filter_fields, key, new_val) result = result and self.create_tap(filter_data) return result # If match fields are exact, then proceed programming switches # Iterate over all the sources and sinks, and collect the individual # hop information. It is possible that a switch is both a source, # a sink and an intermediate hop. for source in filter_data['sources']: for sink in filter_data['sinks']: # Handle error case if source == sink: continue # In basic version, source and sink are same switch if source['dpid'] != sink['dpid']: LOG.debug("Mismatching source and sink switch") return False # ychen modify datapath = self.dpset.get(int(source['dpid'], 16)) # If dpid is invalid, return if datapath is None: LOG.debug("Unable to get datapath for id = %s", str(source['dpid'])) return False ofproto = datapath.ofproto ofproto_parser = datapath.ofproto_parser in_port = source['port_no'] out_port = sink['port_no'] filter_fields = filter_data['fields'].copy() ######## Create action list if out_port == 'Normal': actions = [ ofproto_parser.OFPActionOutput(ofproto.OFPP_NORMAL, 0) ] else: actions = [ofproto_parser.OFPActionOutput(out_port)] ######## Create match if in_port != 'all': # If not sniffing on all in_ports filter_fields['in_port'] = in_port match = ofctl_v1_3.to_match(datapath, filter_fields) ######## Cookie might come handy #cookie = random.randint(0, 0xffffffffffffffff) cookie = 0x1111111111111111 ######## init inst inst = [] ######## meter add if filter_data['qos']: meter_id = int(filter_data['qos']['meter_id']) meter_rate = int(filter_data['qos']['meter_rate']) mod = ofproto_parser.OFPMeterMod( datapath=datapath, command=ofproto.OFPMC_DELETE, flags=10, meter_id=meter_id) datapath.send_msg(mod) band = ofproto_parser.OFPMeterBandDrop(rate=meter_rate, burst_size=1000, type_=1, len_=16) bands = [band] mod = ofproto_parser.OFPMeterMod(datapath=datapath, command=ofproto.OFPMC_ADD, flags=5, meter_id=meter_id, bands=bands) datapath.send_msg(mod) inst.append( ofproto_parser.OFPInstructionMeter(meter_id=meter_id)) inst.append( ofproto_parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions)) # install the flow in the switch if 'udf0' in filter_data['fields']: mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) else: mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) LOG.info("the content of filter is %s ", mod) datapath.send_msg(mod) LOG.debug( "Flow inserted to switch %x: cookie=%s, out_port=%d, match=%s", datapath.id, str(cookie), out_port, str(filter_fields)) LOG.info("Created tap with filter = %s", str(filter_data)) return True
def handle_security(self, dpid, mode, operation): datapath = self.dpset.get(int(dpid, 16)) if datapath is None: LOG.debug("Unable to get datapath for id = %s", str(source['dpid'])) return False ofproto = datapath.ofproto ofproto_parser = datapath.ofproto_parser ##### create meter mode_id = { 'tcp': 250, 'http': 251, 'icmp': 252, 'dns': 253, 'ntp': 254, 'udp_tcp': 255 } meter_id = mode_id[mode] LOG.error(meter_id) meter_rate = 1000 mod = ofproto_parser.OFPMeterMod(datapath=datapath, command=ofproto.OFPMC_DELETE, flags=10, meter_id=meter_id) datapath.send_msg(mod) band = ofproto_parser.OFPMeterBandDrop(rate=meter_rate, burst_size=1000, type_=1, len_=16) bands = [band] mod = ofproto_parser.OFPMeterMod(datapath=datapath, command=ofproto.OFPMC_ADD, flags=5, meter_id=meter_id, bands=bands) datapath.send_msg(mod) #### send flow ######## Cookie might come handy cookie = 0x333333333333333 ######## init inst if operation == 'protect': actions = [ofproto_parser.OFPActionOutput(ofproto.OFPP_NORMAL, 0)] inst = [ ofproto_parser.OFPInstructionMeter(meter_id=meter_id), ofproto_parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions) ] if operation == 'clear': actions = [ofproto_parser.OFPActionOutput(ofproto.OFPP_NORMAL, 0)] inst = [ ofproto_parser.OFPInstructionActions( ofproto.OFPIT_APPLY_ACTIONS, actions) ] ######## Create tcp syc udf match & send flow if mode == 'tcp': tcp_match = {} tcp_match['udf0'] = '0x60000/0xff0000' tcp_match['udf2'] = '0x20000/0xfff0000' match = ofctl_v1_3.to_match(datapath, tcp_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) ######## Create dns query udf match & send flow if mode == 'dns': dns_match = {} dns_match['udf0'] = '0x110000/0xff0000' dns_match['udf1'] = '0x00000035/0x0000ffff' match = ofctl_v1_3.to_match(datapath, dns_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) ######## Create http udf match & send flow if mode == 'http': http_match = {} http_match['udf0'] = '0x60000/0xff0000' http_match['udf1'] = '0x00000050/0x0000ffff' http_match['udf3'] = '0x47455400/0xffffff00' match = ofctl_v1_3.to_match(datapath, http_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) ######## Create icmp udf match & send flow if mode == 'icmp': icmp_match = {} icmp_match['udf0'] = '0x10000/0xff0000' match = ofctl_v1_3.to_match(datapath, icmp_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) ######## Create ntp attack udf match & send flow if mode == 'ntp': ntp_match = {} ntp_match['udf0'] = '0x110000/0xff0000' ntp_match['udf1'] = '0x0000607B/0x0000ffff' match = ofctl_v1_3.to_match(datapath, ntp_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) ######## Create udp/tcp udf match & send flow (2 flows) if mode == 'udp/tcp': udp_tcp_match = {} udp_tcp_match['udf0'] = '0x110000/0xff0000' match = ofctl_v1_3.to_match(datapath, udp_tcp_match) mod = ofproto_parser.OFPFlowMod(datapath=datapath, match=match, table_id=250, priority=1000, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod)
def create_tap(self, filter_data): LOG.debug("Creating tap with filter = %s", str(filter_data)) # If dl_host, nw_host or tp_port are used, the recursively call the individual filters. # This causes the match to expand and more rules to be programmed. result = True filter_data.setdefault('fields', {}) filter_fields = filter_data['fields'] for key, val in self.broadened_field.iteritems(): if key in filter_fields: for new_val in val: filter_data['fields'] = self.change_field(filter_fields, key, new_val) result = result and self.create_tap(filter_data) return result # If match fields are exact, then proceed programming switches # Iterate over all the sources and sinks, and collect the individual # hop information. It is possible that a switch is both a source, # a sink and an intermediate hop. for source in filter_data['sources']: for sink in filter_data['sinks']: # Handle error case if source == sink: continue # In basic version, source and sink are same switch if source['dpid'] != sink['dpid']: LOG.debug("Mismatching source and sink switch") return False datapath = self.dpset.get(source['dpid']) # If dpid is invalid, return if datapath is None: LOG.debug("Unable to get datapath for id = %s", str(source['dpid'])) return False ofproto = datapath.ofproto ofproto_parser = datapath.ofproto_parser in_port = source['port_no'] out_port = sink['port_no'] filter_fields = filter_data['fields'].copy() ######## Create action list actions = [ofproto_parser.OFPActionOutput(out_port)] ######## Create match if in_port != 'all': # If not sniffing on all in_ports filter_fields['in_port'] = in_port match = ofctl_v1_3.to_match(datapath, filter_fields) ######## Cookie might come handy cookie = random.randint(0, 0xffffffffffffffff) inst = [ofproto_parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)] # install the flow in the switch mod = ofproto_parser.OFPFlowMod( datapath=datapath, match=match, command=ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0, instructions=inst, cookie=cookie) datapath.send_msg(mod) LOG.debug("Flow inserted to switch %x: cookie=%s, out_port=%d, match=%s", datapath.id, str(cookie), out_port, str(filter_fields)) LOG.info("Created tap with filter = %s", str(filter_data)) return True
def handler_datapath(self, ev): dp = ev.dp ofproto = dp.ofproto parser = dp.ofproto_parser if ev.enter: self.logger.info("Fireswitch: Switch connected:%s", dp.id) else: self.logger.info("Fireswitch: Switch disconnected:%s", dp.id) return self.logger.info("Configuring datapath") # Make all packet to flow normallyW aclmatch = {} match = ofctl_v1_3.to_match(dp, aclmatch) act_normal = [parser.OFPActionOutput(ofproto.OFPP_NORMAL)] self.add_flow(dp, 0, match, act_normal) # add catchall drop rule to datapath drop_act = [] # Drop ICMP packets aclmatch = {} aclmatch['eth_type'] = ether_types.ETH_TYPE_IP aclmatch['ip_proto'] = 0x1 match = ofctl_v1_3.to_match(dp, aclmatch) self.add_flow(dp, 10000, match, drop_act) act_redirect = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER)] # Redirect UDP and TCP packets aclmatch = {} aclmatch['eth_type'] = ether_types.ETH_TYPE_IP aclmatch['ip_proto'] = in_proto.IPPROTO_UDP match = ofctl_v1_3.to_match(dp, aclmatch) self.add_flow(dp, 1000, match, act_redirect) aclmatch = {} aclmatch['eth_type'] = ether_types.ETH_TYPE_IP aclmatch['ip_proto'] = in_proto.IPPROTO_TCP match = ofctl_v1_3.to_match(dp, aclmatch) self.add_flow(dp, 1000, match, act_redirect) # Redirect DNS packets aclmatch = {} aclmatch['eth_type'] = ether_types.ETH_TYPE_IP aclmatch['ip_proto'] = in_proto.IPPROTO_UDP aclmatch['udp_src'] = 53 match = ofctl_v1_3.to_match(dp, aclmatch) self.add_flow(dp, 1000, match, act_redirect) aclmatch = {} aclmatch['eth_type'] = ether_types.ETH_TYPE_IP aclmatch['ip_proto'] = in_proto.IPPROTO_UDP aclmatch['udp_dst'] = 53 match = ofctl_v1_3.to_match(dp, aclmatch) self.add_flow(dp, 1000, match, act_redirect) # Redirect SNMP packets aclmatch = {} aclmatch['eth_type'] = ether_types.ETH_TYPE_IP aclmatch['ip_proto'] = in_proto.IPPROTO_UDP aclmatch['udp_src'] = 161 match = ofctl_v1_3.to_match(dp, aclmatch) self.add_flow(dp, 1000, match, act_redirect) aclmatch = {} aclmatch['eth_type'] = ether_types.ETH_TYPE_IP aclmatch['ip_proto'] = in_proto.IPPROTO_UDP aclmatch['udp_dst'] = 161 match = ofctl_v1_3.to_match(dp, aclmatch) self.add_flow(dp, 1000, match, act_redirect) aclmatch = {} aclmatch['eth_type'] = ether_types.ETH_TYPE_IP aclmatch['ip_proto'] = in_proto.IPPROTO_TCP aclmatch['tcp_src'] = 161 match = ofctl_v1_3.to_match(dp, aclmatch) self.add_flow(dp, 1000, match, act_redirect) aclmatch = {} aclmatch['eth_type'] = ether_types.ETH_TYPE_IP aclmatch['ip_proto'] = in_proto.IPPROTO_TCP aclmatch['tcp_dst'] = 161 match = ofctl_v1_3.to_match(dp, aclmatch) self.add_flow(dp, 1000, match, act_redirect) self.logger.info("Datapath configured")
def create_match(self, dp, match): return ofctl_v1_3.to_match(dp, match)