def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser # install table-miss flow entry # # We specify NO BUFFER to max_len of the output action due to # OVS bug. At this moment, if we specify a lesser number, e.g., # 128, OVS will send Packet-In with invalid buffer_id and # truncated packet data. In that case, we cannot output packets # correctly. The bug has been fixed in OVS v2.1.0. match = parser.OFPMatch() actions = [ parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] ofp_helper.add_flow(datapath, 0, match, actions) # install DHCP request packets flow entry match_dhcp_request = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_UDP, udp_src=68, udp_dst=67) ofp_helper.add_flow(datapath, 100, match_dhcp_request, actions)
def _packet_in_handler(self, ev): # If you hit this you might want to increase # the "miss_send_length" of your switch if ev.msg.msg_len < ev.msg.total_len: self.logger.debug("packet truncated: only %s of %s bytes", ev.msg.msg_len, ev.msg.total_len) msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) # self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD if in_port == monitor_port: # don't mirror snort traffic actions = [parser.OFPActionOutput(out_port)] else: # add mirror port actions = [parser.OFPActionOutput(out_port), parser.OFPActionOutput(monitor_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=dst) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: ofp_helper.add_flow(datapath, 1, match, actions, msg.buffer_id) return else: ofp_helper.add_flow(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser # ofproto.OFPCML_NO_BUFFER == 65535 (0xFFFF) # We specify NO BUFFER to max_len of the output action due to # OVS bug. At this moment, if we specify a lesser number, e.g., # 128, OVS will send Packet-In with invalid buffer_id and # truncated packet data. In that case, we cannot output packets # correctly. The bug has been fixed in OVS v2.1.0. match = parser.OFPMatch() actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] # set miss_send_length to 1518 self.send_set_config(datapath) # get switch config message self.send_get_config_request(datapath) # install table-miss flow entry ofp_helper.add_flow(datapath, 0, match, actions) # install DHCP request packets flow entry match_dhcp_request = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_UDP, udp_src=68, udp_dst=67) ofp_helper.add_flow(datapath, 100, match_dhcp_request, actions)
def _packet_in_handler(self, ev): msg = ev.msg datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser in_port = msg.match['in_port'] nat_settings = settings.load() wan_port = nat_settings['wan_port'] if in_port == wan_port: # self.logger.info("ignore packet coming from WAN port 3") # ignore packet coming from WAN port return pkt = packet.Packet(msg.data) eth = pkt.get_protocols(ethernet.ethernet)[0] if eth.ethertype == ether_types.ETH_TYPE_LLDP: # ignore lldp packet return dst = eth.dst src = eth.src dpid = datapath.id self.mac_to_port.setdefault(dpid, {}) # self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port) # learn a mac address to avoid FLOOD next time. self.mac_to_port[dpid][src] = in_port if dst in self.mac_to_port[dpid]: out_port = self.mac_to_port[dpid][dst] else: out_port = ofproto.OFPP_FLOOD actions = [parser.OFPActionOutput(out_port)] # install a flow to avoid packet_in next time if out_port != ofproto.OFPP_FLOOD: match = parser.OFPMatch(in_port=in_port, eth_dst=dst) # verify if we have a valid buffer_id, if yes avoid to send both # flow_mod & packet_out if msg.buffer_id != ofproto.OFP_NO_BUFFER: ofp_helper.add_flow(datapath, 1, match, actions, msg.buffer_id) return else: ofp_helper.add_flow(datapath, 1, match, actions) data = None if msg.buffer_id == ofproto.OFP_NO_BUFFER: data = msg.data out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id, in_port=in_port, actions=actions, data=data) datapath.send_msg(out)
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser match = parser.OFPMatch() actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] ofp_helper.add_flow(datapath, match=match, actions=actions, idle_timeout=0, priority=0)
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser # install table-miss flow entry match = parser.OFPMatch() actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER)] ofp_helper.add_flow(datapath, 0, match, actions)
def _reset_flow(self, datapath): parser = datapath.ofproto_parser syn_ack_match = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_TCP, ipv4_src=syn_flow.get('ip_dst'), tcp_src=syn_flow.get('port_dst')) actions = [parser.OFPActionOutput(13)] # to reset counter, delete flow first ofp_helper.del_flow(datapath, syn_ack_match, 100) ofp_helper.add_flow(datapath, 100, syn_ack_match, actions)
def init_packet_in_table(self, datapath): parser = datapath.ofproto_parser ofproto = datapath.ofproto match = parser.OFPMatch() actions = [ parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] ofp_helper.add_flow(datapath, table_id=self.count - 1, priority=self.packet_in_priority, match=match, actions=actions, idle_timeout=0)
def add_block_rule(self, src_ip, dst_ip, protocol, dst_port, src_port): switch_list = get_switch(self.topology_api_app, None) for switch in switch_list: datapath = switch.dp parser = datapath.ofproto_parser actions = [] # drop # initial match field(IP layer) match_dict = self.handle_match(src_ip, dst_ip, protocol, dst_port, src_port) match = parser.OFPMatch(**match_dict) ofp_helper.add_flow(datapath, fw_priority, match, actions, 30)
def add_firewall_rule(self, src_ip, dst_ip, ip_proto, port): switch_list = get_switch(self.topology_api_app, None) for switch in switch_list: datapath = switch.dp parser = datapath.ofproto_parser ofproto = datapath.ofproto match_mapping = self.match_mapping(src_ip, dst_ip, ip_proto, port) match = parser.OFPMatch(**match_mapping) actions = [] # drop ofp_helper.add_flow(datapath, table_id=self.table_id, priority=self.service_priority, match=match, actions=actions) self._request_flow_stats(datapath) # update flow list
def _reset_flow(self, datapath): parser = datapath.ofproto_parser # inport -> outport # inport -> mirror port in_match = parser.OFPMatch(in_port=port_a) in_actions = [parser.OFPActionOutput(port_b), parser.OFPActionOutput(port_ab)] ofp_helper.add_flow(datapath, tap_priority, in_match, in_actions) # outport -> mirror port # outport -> inport out_match = parser.OFPMatch(in_port=port_b) out_actions = [parser.OFPActionOutput(port_a), parser.OFPActionOutput(port_ab)] ofp_helper.add_flow(datapath, tap_priority, out_match, out_actions)
def add_packet_in_flow(self, apply_table_id): switch_list = get_switch(self.topology_api_app, None) for switch in switch_list: datapath = switch.dp parser = datapath.ofproto_parser ofproto = datapath.ofproto match = parser.OFPMatch() actions = [ parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] ofp_helper.add_flow(datapath, table_id=apply_table_id, priority=self.packet_in_priority, match=match, actions=actions, idle_timeout=0)
def add_dhcp_flow(self): switch_list = get_switch(self.topology_api_app, None) for switch in switch_list: datapath = switch.dp parser = datapath.ofproto_parser ofproto = datapath.ofproto match_dhcp_request = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_UDP, udp_src=68, udp_dst=67) actions = [ parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] ofp_helper.add_flow( datapath, table_id=service_config.service_sequence['nat_egress'], priority=service_config.service_priority['dhcp'], match=match_dhcp_request, actions=actions, idle_timeout=0)
def switch_features_handler(self, ev): datapath = ev.msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser # install DHCP request packets flow entry # and dhcp dont need to go to next table match_dhcp_request = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_UDP, udp_src=68, udp_dst=67) actions = [ parser.OFPActionOutput(ofproto.OFPP_CONTROLLER, ofproto.OFPCML_NO_BUFFER) ] ofp_helper.add_flow(datapath, table_id=self.table_id, priority=self.service_priority, match=match_dhcp_request, actions=actions, idle_timeout=0)
def add_block_rule(self, rule_action, src_ip, dst_ip, trans_proto, port): switch_list = get_switch(self.topology_api_app, None) for switch in switch_list: datapath = switch.dp parser = datapath.ofproto_parser actions = [] # drop # initial match field match_dict = {'eth_type': ether.ETH_TYPE_IP} # fill into the layer3 and layer 4 protocol # if port == 0, means block all protocol if port >= 0: if trans_proto == inet.IPPROTO_TCP: match_dict.update({ 'ip_proto': trans_proto, 'tcp_dst': port }) else: # udp match_dict.update({ 'ip_proto': trans_proto, 'udp_dst': port }) if len(src_ip) > 0: # not '' match_dict.update({'ipv4_src': src_ip}) if len(dst_ip) > 0: # not '' match_dict.update({'ipv4_dst': dst_ip}) match = parser.OFPMatch(**match_dict) settings = firewall_settings.load() fw_priority = settings['priority'] if rule_action == 'add': ofp_helper.add_flow(datapath, fw_priority, match, actions) elif rule_action == 'delete': # 'off' ofp_helper.del_flow(datapath, match, fw_priority) self._request_stats(datapath) # update flow list
def add_block_rule(self, rule_action, src_ip, dst_ip, trans_proto, port): switch_list = get_switch(self.topology_api_app, None) for switch in switch_list: datapath = switch.dp parser = datapath.ofproto_parser actions = [] # drop # initial match field match_dict = {'eth_type': ether.ETH_TYPE_IP} # fill into the layer3 and layer 4 protocol # if port == 0, means block all protocol if port >= 0: if trans_proto == inet.IPPROTO_TCP: match_dict.update({'ip_proto': trans_proto, 'tcp_dst': port}) else: # udp match_dict.update({'ip_proto': trans_proto, 'udp_dst': port}) if len(src_ip) > 0: # not '' match_dict.update({'ipv4_src': src_ip}) if len(dst_ip) > 0: # not '' match_dict.update({'ipv4_dst': dst_ip}) match = parser.OFPMatch(**match_dict) settings = firewall_settings.load() fw_priority = settings['priority'] if rule_action == 'add': ofp_helper.add_flow(datapath, fw_priority, match, actions) elif rule_action == 'delete': # 'off' ofp_helper.del_flow(datapath, match, fw_priority) self._request_stats(datapath) # update flow list
def _private_to_public(self, datapath, buffer_id, data, in_port, out_port, pkt_ip, pkt_ethernet, pkt_tcp=None, pkt_udp=None, pkt_icmp=None): if pkt_ip is None: return parser = datapath.ofproto_parser ofproto = datapath.ofproto eth_dst = pkt_ethernet.dst eth_src = pkt_ethernet.src ipv4_src = pkt_ip.src ipv4_dst = pkt_ip.dst nat_port = self._get_available_port() if (self._is_public(ipv4_dst) and not self._in_nat_public_ip_subnetwork(ipv4_dst)): target_ip = self.gateway elif self._in_nat_public_ip_subnetwork(ipv4_dst): target_ip = ipv4_dst elif self._in_private_subnetwork(ipv4_dst): return if pkt_tcp: # print "@@@ Install TCP Flow Entry @@@" tcp_src = pkt_tcp.src_port tcp_dst = pkt_tcp.dst_port match = parser.OFPMatch(in_port=in_port, eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_TCP, ipv4_src=ipv4_src, ipv4_dst=ipv4_dst, tcp_src=tcp_src, tcp_dst=tcp_dst) actions = [parser.OFPActionSetField(eth_dst=IP_TO_MAC_TABLE[target_ip]), parser.OFPActionSetField(ipv4_src=self.nat_public_ip), parser.OFPActionSetField(tcp_src=nat_port), parser.OFPActionOutput(out_port)] match_back = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_TCP, ipv4_src=ipv4_dst, ipv4_dst=self.nat_public_ip, tcp_src=tcp_dst, tcp_dst=nat_port) actions_back = [parser.OFPActionSetField(eth_dst=eth_src), parser.OFPActionSetField(ipv4_dst=ipv4_src), parser.OFPActionSetField(tcp_dst=tcp_src), parser.OFPActionOutput(in_port)] elif pkt_udp: # print "@@@ Install UDP Flow Entry @@@" udp_src = pkt_udp.src_port udp_dst = pkt_udp.dst_port match = parser.OFPMatch(in_port=in_port, eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_UDP, ipv4_src=ipv4_src, ipv4_dst=ipv4_dst, udp_src=udp_src, udp_dst=udp_dst) actions = [parser.OFPActionSetField(eth_dst=IP_TO_MAC_TABLE[target_ip]), parser.OFPActionSetField(ipv4_src=self.nat_public_ip), parser.OFPActionSetField(udp_src=nat_port), parser.OFPActionOutput(out_port)] match_back = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_UDP, ipv4_src=ipv4_dst, ipv4_dst=self.nat_public_ip, udp_src=udp_dst, udp_dst=nat_port) actions_back = [parser.OFPActionSetField(eth_dst=eth_src), parser.OFPActionSetField(ipv4_dst=ipv4_src), parser.OFPActionSetField(udp_dst=udp_src), parser.OFPActionOutput(in_port)] else: pass ofp_helper.add_flow(datapath, match=match, actions=actions, idle_timeout=self.IDLE_TIME, priority=10) ofp_helper.add_flow(datapath, match=match_back, actions=actions_back, idle_timeout=self.IDLE_TIME, priority=10) d = None if buffer_id == ofproto.OFP_NO_BUFFER: d = data out = parser.OFPPacketOut(datapath=datapath, buffer_id=buffer_id, in_port=in_port, actions=actions, data=d) datapath.send_msg(out)
def _handle_ipv4(self, msg, in_port, pkt, pkt_ethernet, pkt_ipv4): datapath = msg.datapath ofproto = datapath.ofproto parser = datapath.ofproto_parser dpid = datapath.id eth_dst = pkt_ethernet.dst eth_src = pkt_ethernet.src # update ip info for members in member_list member_list = forwarding_config.member_list dst_member = member_list[eth_dst] dst_member.ip = pkt_ipv4.dst if member_list.get(eth_src) is not None: src_member = member_list[eth_src] src_member.ip = pkt_ipv4.src out_port = dst_member.port # install layer4 flow for statitic actions = [parser.OFPActionOutput(out_port)] actions_back = [parser.OFPActionOutput(in_port)] if pkt_ipv4.proto == inet.IPPROTO_TCP: pkt_tcp = pkt.get_protocol(tcp.tcp) match = parser.OFPMatch(eth_src=pkt_ethernet.src, eth_dst=pkt_ethernet.dst, eth_type=ether.ETH_TYPE_IP, ipv4_src=pkt_ipv4.src, ipv4_dst=pkt_ipv4.dst, ip_proto=pkt_ipv4.proto, tcp_src=pkt_tcp.src_port, tcp_dst=pkt_tcp.dst_port) match_back = parser.OFPMatch(eth_src=pkt_ethernet.dst, eth_dst=pkt_ethernet.src, eth_type=ether.ETH_TYPE_IP, ipv4_src=pkt_ipv4.dst, ipv4_dst=pkt_ipv4.src, ip_proto=pkt_ipv4.proto, tcp_src=pkt_tcp.dst_port, tcp_dst=pkt_tcp.src_port) elif pkt_ipv4.proto == inet.IPPROTO_UDP: pkt_udp = pkt.get_protocol(udp.udp) match = parser.OFPMatch(eth_src=pkt_ethernet.src, eth_dst=pkt_ethernet.dst, eth_type=ether.ETH_TYPE_IP, ipv4_src=pkt_ipv4.src, ipv4_dst=pkt_ipv4.dst, ip_proto=pkt_ipv4.proto, udp_src=pkt_udp.src_port, udp_dst=pkt_udp.dst_port) match_back = parser.OFPMatch(eth_src=pkt_ethernet.dst, eth_dst=pkt_ethernet.src, eth_type=ether.ETH_TYPE_IP, ipv4_src=pkt_ipv4.dst, ipv4_dst=pkt_ipv4.src, ip_proto=pkt_ipv4.proto, udp_src=pkt_udp.dst_port, udp_dst=pkt_udp.src_port) else: match = parser.OFPMatch(eth_src=pkt_ethernet.src, eth_dst=pkt_ethernet.dst, eth_type=ether.ETH_TYPE_IP, ipv4_src=pkt_ipv4.src, ipv4_dst=pkt_ipv4.dst) match_back = parser.OFPMatch(eth_src=pkt_ethernet.dst, eth_dst=pkt_ethernet.src, eth_type=ether.ETH_TYPE_IP, ipv4_src=pkt_ipv4.dst, ipv4_dst=pkt_ipv4.src) ofp_helper.add_flow(datapath, table_id=1, priority=self.service_priority, match=match, actions=actions, idle_timeout=10) ofp_helper.add_flow(datapath, table_id=1, priority=self.service_priority, match=match_back, actions=actions_back, idle_timeout=10) ofp_helper.send_packet_out(msg, in_port, actions)
def _private_to_public(self, datapath, buffer_id, data, in_port, out_port, pkt_ip, pkt_ethernet, pkt_tcp=None, pkt_udp=None, pkt_icmp=None): if pkt_ip is None: return parser = datapath.ofproto_parser ofproto = datapath.ofproto eth_dst = pkt_ethernet.dst eth_src = pkt_ethernet.src ipv4_src = pkt_ip.src ipv4_dst = pkt_ip.dst nat_port = self._get_available_port() if (self._is_public(ipv4_dst) and not self._in_public_ip_subnetwork(ipv4_dst)): target_ip = self.public_gateway elif self._in_public_ip_subnetwork(ipv4_dst): target_ip = ipv4_dst elif self._in_private_subnetwork(ipv4_dst): return if pkt_tcp: # Install TCP Flow Entry tcp_src = pkt_tcp.src_port tcp_dst = pkt_tcp.dst_port # egress match = parser.OFPMatch(in_port=in_port, eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_TCP, ipv4_src=ipv4_src, ipv4_dst=ipv4_dst, tcp_src=tcp_src, tcp_dst=tcp_dst) actions = [ parser.OFPActionSetField(eth_dst=IP_TO_MAC_TABLE[target_ip]), parser.OFPActionSetField(ipv4_src=self.public_ip), parser.OFPActionSetField(tcp_src=nat_port) ] forward_actions = [parser.OFPActionOutput(out_port)] # ingress match_back = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_TCP, ipv4_src=ipv4_dst, ipv4_dst=self.public_ip, tcp_src=tcp_dst, tcp_dst=nat_port) actions_back = [ parser.OFPActionSetField(eth_dst=eth_src), parser.OFPActionSetField(ipv4_dst=ipv4_src), parser.OFPActionSetField(tcp_dst=tcp_src) ] forward_match_back = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_TCP, ipv4_src=ipv4_dst, ipv4_dst=ipv4_src, tcp_src=tcp_dst, tcp_dst=tcp_src) forward_actions_back = [parser.OFPActionOutput(in_port)] elif pkt_udp: # Install UDP Flow Entry udp_src = pkt_udp.src_port udp_dst = pkt_udp.dst_port # egress, inside-to-outside match = parser.OFPMatch(in_port=in_port, eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_UDP, ipv4_src=ipv4_src, ipv4_dst=ipv4_dst, udp_src=udp_src, udp_dst=udp_dst) actions = [ parser.OFPActionSetField(eth_dst=IP_TO_MAC_TABLE[target_ip]), parser.OFPActionSetField(ipv4_src=self.public_ip), parser.OFPActionSetField(udp_src=nat_port) ] forward_actions = [parser.OFPActionOutput(out_port)] # ingress, outside-to-inside match_back = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_UDP, ipv4_src=ipv4_dst, ipv4_dst=self.public_ip, udp_src=udp_dst, udp_dst=nat_port) actions_back = [ parser.OFPActionSetField(eth_dst=eth_src), parser.OFPActionSetField(ipv4_dst=ipv4_src), parser.OFPActionSetField(udp_dst=udp_src) ] forward_match_back = parser.OFPMatch(eth_type=ether.ETH_TYPE_IP, ip_proto=inet.IPPROTO_UDP, ipv4_src=ipv4_dst, ipv4_dst=ipv4_src, udp_src=udp_dst, udp_dst=udp_src) forward_actions_back = [parser.OFPActionOutput(in_port)] else: pass # outside - inside set-filed (Table 0) ofp_helper.add_flow_with_next(datapath, table_id=self.ingress_table_id, priority=self.service_priority, match=match_back, actions=actions_back, idle_timeout=self.IDLE_TIME) # inside - outside go-to-next (Table 0) ofp_helper.add_flow_goto_next(datapath, table_id=self.ingress_table_id, priority=self.service_priority, match=match, idle_timeout=self.IDLE_TIME) # outside - inside out-port (Table 3) ofp_helper.add_flow(datapath, table_id=self.forward_table_id, priority=self.service_priority, match=forward_match_back, actions=forward_actions_back, idle_timeout=self.IDLE_TIME) # inside - outside write-out-port(Table 3) ofp_helper.add_write_flow_with_next(datapath, table_id=self.forward_table_id, priority=self.service_priority, match=match, actions=forward_actions, idle_timeout=self.IDLE_TIME) # inside - outside set-field( Table 4) ofp_helper.add_flow(datapath, table_id=self.egress_table_id, priority=self.service_priority, match=match, actions=actions, idle_timeout=self.IDLE_TIME) # send first packet back to switch d = None if buffer_id == ofproto.OFP_NO_BUFFER: d = data out = parser.OFPPacketOut(datapath=datapath, buffer_id=buffer_id, in_port=in_port, actions=actions, data=d) datapath.send_msg(out)