def all_stats_get(parent): """ Get the aggregate stats for all flows in the table @param parent Test instance with controller connection and assert @returns dict with keys flows, packets, bytes, active (flows), lookups, matched """ stat_req = message.aggregate_stats_request() stat_req.match = ofp.ofp_match() stat_req.match.wildcards = ofp.OFPFW_ALL stat_req.table_id = 0xff stat_req.out_port = ofp.OFPP_NONE rv = {} (reply, pkt) = parent.controller.transact(stat_req, timeout=2) parent.assertTrue(len(reply.stats) == 1, "Did not receive flow stats reply") for obj in reply.stats: (rv["flows"], rv["packets"], rv["bytes"]) = (obj.flow_count, obj.packet_count, obj.byte_count) break request = message.table_stats_request() (reply , pkt) = parent.controller.transact(request, timeout=2) (rv["active"], rv["lookups"], rv["matched"]) = (0,0,0) for obj in reply.stats: rv["active"] += obj.active_count rv["lookups"] += obj.lookup_count rv["matched"] += obj.matched_count return rv
def all_stats_get(parent): """ Get the aggregate stats for all flows in the table @param parent Test instance with controller connection and assert @returns dict with keys flows, packets, bytes, active (flows), lookups, matched """ stat_req = message.aggregate_stats_request() stat_req.match = ofp.ofp_match() stat_req.match.wildcards = ofp.OFPFW_ALL stat_req.table_id = 0xff stat_req.out_port = ofp.OFPP_NONE rv = {} (reply, pkt) = parent.controller.transact(stat_req) parent.assertTrue( len(reply.stats) == 1, "Did not receive flow stats reply") for obj in reply.stats: (rv["flows"], rv["packets"], rv["bytes"]) = (obj.flow_count, obj.packet_count, obj.byte_count) break request = message.table_stats_request() (reply, pkt) = parent.controller.transact(request) (rv["active"], rv["lookups"], rv["matched"]) = (0, 0, 0) for obj in reply.stats: rv["active"] += obj.active_count rv["lookups"] += obj.lookup_count rv["matched"] += obj.matched_count return rv
def runTest(self): msg, pkt = self.controller.transact(message.table_stats_request()) num_flows = msg.stats[0].max_entries requests = [] for i in range(num_flows): match = ofp.ofp_match() match.wildcards = ofp.OFPFW_ALL & ~ofp.OFPFW_DL_VLAN & ~ofp.OFPFW_DL_DST match.dl_vlan = ofp.OFP_VLAN_NONE match.dl_dst = [0, 1, 2, 3, i / 256, i % 256] act = action.action_output() act.port = ofp.OFPP_CONTROLLER request = message.flow_mod() request.command = ofp.OFPFC_ADD request.buffer_id = 0xffffffff request.priority = num_flows - i request.out_port = ofp.OFPP_NONE request.match = match request.actions.add(act) requests.append(request) for i in range(5): logging.info("Iteration %d: delete all flows" % i) self.assertEqual(delete_all_flows(self.controller), 0, "Failed to delete all flows") self.checkBarrier() logging.info("Iteration %d: add %s flows" % (i, num_flows)) for request in requests: self.assertNotEqual(self.controller.message_send(request), -1, "Error installing flow mod") self.checkBarrier()
def make_match(dl_type=MT_TEST_DL_TYPE, ip_src=MT_TEST_IP): """ Make matching entry template """ match = ofp.ofp_match() match.length = ofp.OFPMT_STANDARD_LENGTH testutils.wildcard_all_set(match) match.wildcards -= ofp.OFPFW_DL_TYPE match.nw_src = parse.parse_ip(ip_src) match.nw_src_mask = 0 # Match nw_src match.dl_type = dl_type return match
def runTest(self): delete_all_flows(self.controller) match = ofp.ofp_match() match.wildcards = 0 stat_req = message.flow_stats_request() stat_req.match = match stat_req.table_id = 0xff stat_req.out_port = ofp.OFPP_NONE response, pkt = self.controller.transact(stat_req) self.assertTrue(response is not None, "No response to stats request") self.assertEquals(len(response.stats), 0) self.assertEquals(response.flags, 0)
def runTest(self): rc = delete_all_flows(self.controller) self.assertEqual(rc, 0, "Failed to delete all flows") match = ofp.ofp_match() match.wildcards = 0 stat_req = message.flow_stats_request() stat_req.match = match stat_req.table_id = 0xff stat_req.out_port = ofp.OFPP_NONE response, pkt = self.controller.transact(stat_req) self.assertTrue(response is not None, "No response to stats request") self.assertEquals(len(response.stats), 0) self.assertEquals(response.flags, 0)
def runTest(self): delete_all_flows(self.controller) match = ofp.ofp_match() match.wildcards = 0 stat_req = message.aggregate_stats_request() stat_req.match = match stat_req.table_id = 0xff stat_req.out_port = ofp.OFPP_NONE response, pkt = self.controller.transact(stat_req) self.assertTrue(response is not None, "No response to stats request") self.assertTrue(len(response.stats) == 1, "Did not receive flow stats reply") self.assertEquals(response.stats[0].flow_count, 0) self.assertEquals(response.stats[0].packet_count, 0) self.assertEquals(response.stats[0].byte_count, 0)
def scenario3(self, first_table=0, second_table=1, third_table=2): """ Add three flow entries: First Table; Match IP Src A; goto Second Table Second Table; Match IP Src A; send to 1, goto Third Table Third Table; Match TCP port B; send to 2 Then send in 2 packets: IP A, TCP C; expect out port 1 IP A, TCP B; expect out port 2 @param self object instance @param first_table first table @param second_table second table @param third_table third table """ of_ports = testutils.clear_switch(self, pa_port_map.keys(), pa_logger) # Set up first match write_goto(self, first_table, second_table) # Set up second match write_goto_output(self, second_table, third_table, of_ports[0]) # Set up third match match = ofp.ofp_match() match.length = ofp.OFPMT_STANDARD_LENGTH testutils.wildcard_all_set(match) match.wildcards -= ofp.OFPFW_DL_TYPE match.wildcards -= ofp.OFPFW_TP_SRC match.dl_type = MT_TEST_DL_TYPE match.nw_proto = 6 #TCP match.tp_src = 80 write_output(self, third_table, of_ports[1], match=match) # Generate a packet matching only flow 1 and 2; rcv on port[0] reply_check_dp(self, tcp_sport=10, ing_port=of_ports[2], egr_port=of_ports[0]) # Generate a packet matching both flow 1, 2 and 3; rcv on port[1] reply_check_dp(self, tcp_sport=80, ing_port=of_ports[2], egr_port=of_ports[1])
def __init__(self, in_port=None, data=""): # Use entries in match when possible. self.in_port = in_port self.data = data self.bytes = len(data) self.match = ofp.ofp_match() self.logger = logging.getLogger("packet") self.instructions = [] # parsable tags self.ip_header_offset = None self.tcp_header_offset = None self.mpls_tag_offset = None # pointer to outer mpls tag self.vlan_tag_offset = None # pointer to outer vlan tag self.action_set = {} self.queue_id = 0 if self.data != "": self.parse()
def runTest(self): rc = delete_all_flows(self.controller) self.assertEqual(rc, 0, "Failed to delete all flows") match = ofp.ofp_match() match.wildcards = 0 stat_req = message.aggregate_stats_request() stat_req.match = match stat_req.table_id = 0xff stat_req.out_port = ofp.OFPP_NONE response, pkt = self.controller.transact(stat_req) self.assertTrue(response is not None, "No response to stats request") self.assertTrue(len(response.stats) == 1, "Did not receive flow stats reply") self.assertEquals(response.stats[0].flow_count, 0) self.assertEquals(response.stats[0].packet_count, 0) self.assertEquals(response.stats[0].byte_count, 0)
def scenario3(self, first_table = 0, second_table = 1, third_table = 2): """ Add three flow entries: First Table; Match IP Src A; goto Second Table Second Table; Match IP Src A; send to 1, goto Third Table Third Table; Match TCP port B; send to 2 Then send in 2 packets: IP A, TCP C; expect out port 1 IP A, TCP B; expect out port 2 @param self object instance @param first_table first table @param second_table second table @param third_table third table """ of_ports = testutils.clear_switch(self, pa_port_map.keys(), pa_logger) # Set up first match write_goto(self, first_table, second_table) # Set up second match write_goto_output(self, second_table, third_table, of_ports[0]) # Set up third match match = ofp.ofp_match() match.length = ofp.OFPMT_STANDARD_LENGTH testutils.wildcard_all_set(match) match.wildcards -= ofp.OFPFW_DL_TYPE match.wildcards -= ofp.OFPFW_NW_PROTO match.wildcards -= ofp.OFPFW_TP_SRC match.dl_type = MT_TEST_DL_TYPE match.nw_proto = 6 #TCP match.tp_src = 80 write_output(self, third_table, of_ports[1], match=match) # Generate a packet matching only flow 1 and 2; rcv on port[0] reply_check_dp(self, tcp_sport=10, ing_port = of_ports[2], egr_port = of_ports[0]) # Generate a packet matching both flow 1, 2 and 3; rcv on port[1] reply_check_dp(self, tcp_sport=80, ing_port = of_ports[2], egr_port = of_ports[1])
def runTest(self): msg = message.flow_stats_entry() match = ofp.ofp_match() match.wildcards &= ~ofp.OFPFW_IN_PORT act = action.action_output() act.port = 3 msg.match = match pkt = msg.pack() self.assertEqual(len(pkt), 136) inst = instruction.instruction_apply_actions() self.assertTrue(inst.actions.add(act), "Could not add action") self.assertTrue(msg.instructions.add(inst), "Could not add instructions") #self.assertTrue(msg.actions.add(act), "Could not add action") pkt = msg.pack() # 160 = 136 for flow_stats_entry and 24 for instruction_list self.assertEqual(len(pkt), 160) rep = message.flow_stats_reply() self.assertEqual(len(rep.pack()),12) rep.stats.append(msg) self.assertEqual(len(rep.pack()),172)
def runTest(self): msg, pkt = self.controller.transact(message.table_stats_request()) # Some switches report an extremely high max_entries that would cause # us to run out of memory attempting to create all the flow-mods. num_flows = min(msg.stats[0].max_entries, 32678) logging.info("Creating %d flow-mods messages", num_flows) requests = [] for i in range(num_flows): match = ofp.ofp_match() match.wildcards = ofp.OFPFW_ALL & ~ofp.OFPFW_DL_VLAN & ~ofp.OFPFW_DL_DST match.dl_vlan = ofp.OFP_VLAN_NONE match.dl_dst = [0, 1, 2, 3, i / 256, i % 256] act = action.action_output() act.port = ofp.OFPP_CONTROLLER request = message.flow_mod() request.command = ofp.OFPFC_ADD request.buffer_id = 0xffffffff request.priority = num_flows - i request.out_port = ofp.OFPP_NONE request.match = match request.actions.add(act) requests.append(request) for i in range(3): logging.info("Iteration %d: delete all flows" % i) delete_all_flows(self.controller) self.checkBarrier() logging.info("Iteration %d: add %s flows" % (i, num_flows)) random.shuffle(requests) for request in requests: self.assertNotEqual(self.controller.message_send(request), -1, "Error installing flow mod") self.checkBarrier()
def runTest(self): logging = get_logger() logging.info("Running Grp40No190: Delete with constraint out_port") ports = config["port_map"].keys() ports.sort() self.assertTrue(len(ports) > 2, "Not enough ports exist for this test.") ok = delete_all_flows(self.controller) self.assertEqual(ok, 0, "Could not delete all flows.") ok = do_barrier(self.controller) self.assertEqual(ok, 0, "Barrier request failed.") # Craft a match with all fields but OFPFW_IN_PORT wildcarded. match = ofp.ofp_match() match.wildcards = ofp.OFPFW_ALL & ~ofp.OFPFW_IN_PORT match.in_port = ports[0] pkt = simple_tcp_packet() fmod = message.flow_mod() fmod.buffer_id = 0xffffffff fmod.command = ofp.OFPFC_ADD fmod.match = match fmod.actions = action_list.action_list() act = action.action_output() act.port = ports[1] fmod.actions.add(act) fmod.priority = 12 ok = self.controller.message_send(fmod) self.assertNotEqual(ok, -1, "Error occurred while installing flow mod.") fmod.actions = action_list.action_list() act = action.action_output() act.port = ports[2] fmod.actions.add(act) fmod.priority = 11 ok = self.controller.message_send(fmod) self.assertNotEqual(ok, -1, "Error occurred while installing flow mod.") ok = do_barrier(self.controller) self.assertEqual(ok, 0, "Barrier request failed.") # Verify data plane traffic is forwarded correctly. self.dataplane.send(ports[0], str(pkt)) invalid = [ports[0], ports[2]] valid = [ports[1]] receive_pkt_check(self.dataplane, pkt, valid, invalid, self) # Send flow_mod with command set to delete. This will delete the # flow that forwards pkt out to ports[1]. dmod = message.flow_mod() dmod.buffer_id = 0xffffffff dmod.command = ofp.OFPFC_DELETE dmod.match = match # Use the match that was used above. dmod.out_port = ports[1] # Add additional match contraint. ok = self.controller.message_send(dmod) self.assertNotEqual(ok, -1, "Error occurred while deleting flow mod.") ok = do_barrier(self.controller) self.assertEqual(ok, 0, "Barrier request failed.") # Verify data plane traffic is forwarded correctly. self.dataplane.send(ports[0], str(pkt)) invalid = [ports[0], ports[1]] valid = [ports[2]] receive_pkt_check(self.dataplane, pkt, valid, invalid, self)
def runTest(self): of_ports = pa_port_map.keys() of_ports.sort() self.assertTrue(len(of_ports) > 2, "Not enough ports for test") # Clear flow table rv = testutils.initialize_table_config(self.controller, pa_logger) self.assertEqual(rv, 0, "Failed to initialize table config") rv = testutils.delete_all_flows(self.controller, pa_logger) self.assertEqual(rv, 0, "Failed to delete all flows") # Set up first match match = ofp.ofp_match() match.length = ofp.OFPMT_STANDARD_LENGTH testutils.wildcard_all_set(match) match.wildcards -= ofp.OFPFW_DL_TYPE match.nw_src_mask = 0 # Match nw_src match.dl_type = 0x800 match.nw_src = parse.parse_ip("192.168.1.10") act = action.action_output() act.port = of_ports[0] request = message.flow_mod() request.match = match request.buffer_id = 0xffffffff request.table_id = 0 inst = instruction.instruction_write_actions() self.assertTrue(inst.actions.add(act), "Could not add action") self.assertTrue(request.instructions.add(inst), "Could not add inst1") inst = instruction.instruction_goto_table() inst.table_id = 1 self.assertTrue(request.instructions.add(inst), "Could not add inst2") pa_logger.info("Inserting flow 1") rv = self.controller.message_send(request) # pa_logger.debug(request.show()) self.assertTrue(rv != -1, "Error installing flow mod") # Set up second match match = ofp.ofp_match() match.length = ofp.OFPMT_STANDARD_LENGTH testutils.wildcard_all_set(match) match.wildcards -= ofp.OFPFW_DL_TYPE match.wildcards -= ofp.OFPFW_TP_SRC match.dl_type = 0x800 match.nw_proto = 6 # TCP match.tp_src = 80 act = action.action_output() act.port = of_ports[1] request = message.flow_mod() request.match = match request.buffer_id = 0xffffffff request.table_id = 1 inst = instruction.instruction_write_actions() self.assertTrue(inst.actions.add(act), "Could not add action") self.assertTrue(request.instructions.add(inst), "Could not add inst3") pa_logger.info("Inserting flow 2") # pa_logger.debug(request.show()) rv = self.controller.message_send(request) self.assertTrue(rv != -1, "Error installing flow mod") testutils.do_barrier(self.controller) # Generate a packet matching only flow 1; rcv on port[0] pkt = testutils.simple_tcp_packet(ip_src='192.168.1.10', tcp_sport=10) self.dataplane.send(of_ports[2], str(pkt)) (rcv_port, rcv_pkt, _) = self.dataplane.poll(timeout=5) self.assertTrue(rcv_pkt is not None, "Did not receive packet") pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " + str(rcv_port)) self.assertEqual(rcv_port, of_ports[0], "Unexpected receive port") # Generate a packet matching both flow 1 and flow 2; rcv on port[1] pkt = testutils.simple_tcp_packet(ip_src='192.168.1.10', tcp_sport=80) self.dataplane.send(of_ports[2], str(pkt)) (rcv_port, rcv_pkt, _) = self.dataplane.poll(timeout=5) self.assertTrue(rcv_pkt is not None, "Did not receive packet") pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " + str(rcv_port)) self.assertEqual(rcv_port, of_ports[1], "Unexpected receive port")
def runTest(self): match = ofp.ofp_match() self.assertEqual(len(match.pack()), 88)
def runTest(self): logging = get_logger() logging.info("Running Grp40No190: Delete with constraint out_port") ports = config["port_map"].keys() ports.sort() self.assertTrue( len(ports) > 2, "Not enough ports exist for this test.") ok = delete_all_flows(self.controller) self.assertEqual(ok, 0, "Could not delete all flows.") ok = do_barrier(self.controller) self.assertEqual(ok, 0, "Barrier request failed.") # Craft a match with all fields but OFPFW_IN_PORT wildcarded. match = ofp.ofp_match() match.wildcards = ofp.OFPFW_ALL & ~ofp.OFPFW_IN_PORT match.in_port = ports[0] pkt = simple_tcp_packet() fmod = message.flow_mod() fmod.buffer_id = 0xffffffff fmod.command = ofp.OFPFC_ADD fmod.match = match fmod.actions = action_list.action_list() act = action.action_output() act.port = ports[1] fmod.actions.add(act) fmod.priority = 12 ok = self.controller.message_send(fmod) self.assertNotEqual(ok, -1, "Error occurred while installing flow mod.") fmod.actions = action_list.action_list() act = action.action_output() act.port = ports[2] fmod.actions.add(act) fmod.priority = 11 ok = self.controller.message_send(fmod) self.assertNotEqual(ok, -1, "Error occurred while installing flow mod.") ok = do_barrier(self.controller) self.assertEqual(ok, 0, "Barrier request failed.") # Verify data plane traffic is forwarded correctly. self.dataplane.send(ports[0], str(pkt)) invalid = [ports[0], ports[2]] valid = [ports[1]] receive_pkt_check(self.dataplane, pkt, valid, invalid, self) # Send flow_mod with command set to delete. This will delete the # flow that forwards pkt out to ports[1]. dmod = message.flow_mod() dmod.buffer_id = 0xffffffff dmod.command = ofp.OFPFC_DELETE dmod.match = match # Use the match that was used above. dmod.out_port = ports[1] # Add additional match contraint. ok = self.controller.message_send(dmod) self.assertNotEqual(ok, -1, "Error occurred while deleting flow mod.") ok = do_barrier(self.controller) self.assertEqual(ok, 0, "Barrier request failed.") # Verify data plane traffic is forwarded correctly. self.dataplane.send(ports[0], str(pkt)) invalid = [ports[0], ports[1]] valid = [ports[2]] receive_pkt_check(self.dataplane, pkt, valid, invalid, self)
def packet_to_flow_match(packet): """ Create a flow match that matches packet with the given wildcards @param packet The packet to use as a flow template @param pkt_format Currently only L2 is supported. Will indicate the overall packet type for parsing @return An ofp_match object if successful. None if format is not recognized. The wildcards of the match will be cleared for the values extracted from the packet. @todo check min length of packet @todo Check if packet is other than L2 format @todo Implement ICMP and ARP fields """ match = ofp.ofp_match() match.type = ofp.OFPMT_STANDARD match.length = ofp.OFPMT_STANDARD_LENGTH match.wildcards = ofp.OFPFW_ALL match.dl_dst = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00] match.dl_dst_mask = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff] match.dl_src = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00] match.dl_src_mask = [0xff, 0xff, 0xff, 0xff, 0xff, 0xff] match.nw_src = 0x00000000 match.nw_src_mask = 0xffffffff match.nw_dst = 0x00000000 match.nw_dst_mask = 0xffffffff match.metadata = 0x0000000000000000 match.metadata_mask = 0xffffffffffffffff if Ether in packet: ether = packet[Ether] match.dl_dst = parse_mac(ether.dst) match.dl_dst_mask = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00] match.dl_src = parse_mac(ether.src) match.dl_src_mask = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00] match.dl_type = ether.type match.wildcards &= ~ofp.OFPFW_DL_TYPE else: return match if Dot1Q in packet: #TODO: nicer way to get last vlan tag? vlan = packet[Dot1Q:0] match.dl_vlan = vlan.vlan match.dl_vlan_pcp = vlan.prio vlan_pl = vlan.payload while vlan_pl is not None and vlan_pl.name == Dot1Q.name: vlan = vlan_pl vlan_pl = vlan.payload match.dl_type = vlan.type else: match.dl_vlan = ofp.OFP_VLAN_NONE match.wildcards &= ~ofp.OFPFW_DL_VLAN match.dl_vlan_pcp = 0 match.wildcards &= ~ofp.OFPFW_DL_VLAN_PCP #TODO ARP if MPLS in packet: mpls = packet[MPLS:0] match.mpls_label = mpls.label match.wildcards &= ~ofp.OFPFW_MPLS_LABEL match.mpls_tc = mpls.cos match.wildcards &= ~ofp.OFPFW_MPLS_TC return match if IP in packet: ip = packet[IP] match.nw_src = parse_ip(ip.src) match.nw_src_mask = 0x00000000 match.nw_dst = parse_ip(ip.dst) match.nw_dst_mask = 0x00000000 match.nw_tos = ip.tos match.wildcards &= ~ofp.OFPFW_NW_TOS else: return match if TCP in packet: tcp = packet[TCP] match.nw_proto = 6 match.wildcards &= ~ofp.OFPFW_NW_PROTO match.tp_src = tcp.sport match.wildcards &= ~ofp.OFPFW_TP_SRC match.tp_dst = tcp.dport match.wildcards &= ~ofp.OFPFW_TP_DST return match if UDP in packet: udp = packet[UDP] match.nw_proto = 17 match.wildcards &= ~ofp.OFPFW_NW_PROTO match.tp_src = udp.sport match.wildcards &= ~ofp.OFPFW_TP_SRC match.tp_dst = udp.dport match.wildcards &= ~ofp.OFPFW_TP_DST return match if ICMP in packet: icmp = packet[ICMP] match.nw_proto = 1 match.wildcards &= ~ofp.OFPFW_NW_PROTO match.tp_src = icmp.type match.wildcards &= ~ofp.OFPFW_TP_SRC match.tp_dst = icmp.code match.wildcards &= ~ofp.OFPFW_TP_DST return match return match