def stop_and_get_result(self): """ Terminates the pktgen process and parses the pktgen result. Returns the PktgenResult object. """ util.run_ssh('pkill -2 pktgen_wrapper', hostname=self.config.pktgen_host).wait() time.sleep(2) return self._parse_result()
def send_trigger_packet(): """ Sends a reference packet to the controller, from which flow-mods or pkt-outs can be constructed. Blocks until the packet is sent. """ util.ping_test(how_many_pings=4, dest_host=config.active_config.source_ip) util.run_ssh('iperf -u -c ', config.active_config.dest_ip, ' -p ', TRIGGER_PORT, ' -t 1 -l 12', hostname=config.active_config.source_ip).wait()
def _parse_result(self): """ Parses the pktgen result file in /proc, extracts the actual run time (in second) and packet count and returns them as a PktgenResult object.. We want to match the following line: Result: OK: 8648151(c650366+d7997785) nsec, 87129 (1400byte,0frags) [ ] <-exp time in us [ ] <- pkt sent """ p_proc = util.run_ssh('cat ', self.config.pktgen_proc, self.config.pktgen_iface, hostname=self.config.pktgen_host, stdout=subprocess.PIPE) result_regex = re.compile('OK: (\d+)\(.*\) nsec, (\d+) \(.*\)') for line in p_proc.stdout: r_obj = result_regex.search(line) if r_obj: print 'Parsing pktgen result:', line result = PktgenResult() result.running_time = int(r_obj.group(1)) / 1000000.0 result.sent_pkt_count = int(r_obj.group(2)) return result raise Exception('Unable to parse pktgen result.')
def dump_tables(self, filter_str="table_id=0"): """ Returns a list of rules in the TCAM (table_id = 0). """ p = util.run_ssh( self.config.dump_flows_cmd, hostname=self.config.ofctl_ip, stdout=subprocess.PIPE, verbose=False ) return [line for line in p.stdout if line.find(filter_str) >= 0]
def reset_flow_table(self): """ Removes all entries from all the flow tables. """ p = util.run_ssh(self.config.del_flow_cmd, hostname=self.config.ofctl_ip) p.wait() # Let system stabilize. time.sleep(4)
def new_wildcard_rules(): conf = config.active_config switch = Switch(conf) switch.reset_flow_table() new_tcp_rule1 = 'cookie=0, priority=32768, idle_timeout=3600,hard_timeout=3600,tcp,in_port=' + \ conf.source_of_port + ',dl_src=' + \ conf.source_mac + ',dl_dst=' + conf.dest_mac + ',nw_src=' + \ conf.source_ip + ',nw_dst=' + conf.dest_ip + \ ',actions=output:' + conf.dest_of_port new_tcp_rule2 = 'cookie=0, priority=32768, idle_timeout=3600,hard_timeout=3600,tcp,in_port=' + \ conf.dest_of_port + ',dl_src=' + \ conf.dest_mac + ',dl_dst=' + conf.source_mac + ',nw_src=' + \ conf.dest_ip + ',nw_dst=' + conf.source_ip + \ ',actions=output:' + conf.source_of_port for rule in [new_tcp_rule1, new_tcp_rule2]: add_rule_cmd = conf.add_rule_cmd(rule) util.run_ssh(add_rule_cmd, hostname=conf.ofctl_ip, verbose=True)
def start_controller(): """ Returns a Popen object. """ cmd = ['cd ~/swclone;', 'export PYTHONPATH=$PYTHONPATH:`pwd`;', 'cd ~/swclone/lib;', 'export PYTHONPATH=$PYTHONPATH:`pwd`;', 'cd ~/swclone;', POX_CMD ] return util.run_ssh(*cmd, verbose=True, hostname=FLEXI_CONTROLLER_HOST, user=FLEXI_CONTROLLER_SSH_USERNAME, port=FLEXI_CONTROLLER_SSH_PORT)
def main(): """ Command-line utility. """ if "dump" in sys.argv: sw_cmd = config.active_config.dump_flows_cmd elif "del" in sys.argv: sw_cmd = config.active_config.del_flow_cmd else: print 'Enter "dump" or "del".' exit(1) p = util.run_ssh(sw_cmd, hostname=config.active_config.ofctl_ip) p.wait()
def add_rules(self, rule_count, wait_and_verify=True, base_port_number=10000, table_id_filter="table_id=0"): """ Adds specified number of rules into the TCAM (table_id = 0). Ensures that fewer than 8 rules are added every second. Returns the number of rules added to the TCAM from this function call. TODO: For wait-and-verify, impose a checkpoint upon every verification. If verification fails, we can delete the newly added rules, roll back to the checkpoint, and re-try. """ initial_flow_count = len(self.dump_tables(filter=table_id_filter)) p_list = [] for flow_id in range(rule_count): port = flow_id + base_port_number p = util.run_ssh( self.config.add_rule_cmd(self.config.new_rule(port)), hostname=self.config.ofctl_ip, stdout=subprocess.PIPE, verbose=False, ) if wait_and_verify: p.wait() # Verifies the TCAM for every ten rules added. if flow_id % 10 == 0: assert len(self.dump_tables(filter=table_id_filter)) - initial_flow_count == flow_id + 1 sys.stdout.write("\radd_rules: %d left" % (rule_count - flow_id)) sys.stdout.flush() else: sys.stdout.write("\radd_rules: %d left" % (rule_count - flow_id)) sys.stdout.flush() p_list += [p] time.sleep(0.3) print "" # Wait for all processes to finish for p in p_list: p.wait() return len(self.dump_tables(filter=table_id_filter)) - initial_flow_count
def new_exact_match_rules(wait_and_verify=True, reset_flow_table=True, rule_count=CLIENT_COUNT, flow_table_filter=FLOW_TABLE_FILTER, client_base_port=CLIENT_BASE_PORT): conf = config.active_config switch = Switch(conf) if reset_flow_table: switch.reset_flow_table() # From client to redis server. new_tcp_rule1 = lambda client_id: \ 'cookie=0,idle_timeout=0,hard_timeout=0,tcp,nw_tos=0x00,' + \ 'dl_vlan=0xffff,dl_vlan_pcp=0x00,dl_src=' + \ conf.dest_mac + ',dl_dst=' + conf.source_mac + ',nw_src=' + \ conf.dest_ip + ',nw_dst=' + conf.source_ip + \ ',tp_src=' + str(client_id + client_base_port) + \ ',tp_dst=' + str(REDIS_PORT) + \ ',actions=output:' + conf.source_of_port # From server back to client. new_tcp_rule2 = lambda client_id: \ 'cookie=0,idle_timeout=0,hard_timeout=0,tcp,nw_tos=0x00,' + \ 'dl_vlan=0xffff,dl_vlan_pcp=0x00,dl_src=' + \ conf.source_mac + ',dl_dst=' + conf.dest_mac + ',nw_src=' + \ conf.source_ip + ',nw_dst=' + conf.dest_ip + \ ',tp_dst=' + str(client_id + client_base_port) + \ ',tp_src=' + str(REDIS_PORT) + \ ',actions=output:' + conf.dest_of_port initial_rule_count = len(switch.dump_tables(filter_str=flow_table_filter)) for client_id in range(rule_count): # Add the rules first. for rule_f in [new_tcp_rule1, new_tcp_rule2]: proc = util.run_ssh(conf.add_rule_cmd(rule_f(client_id)), hostname=conf.ofctl_ip, verbose=True, stdout=subprocess.PIPE) if wait_and_verify or (client_id % 5 == 0): proc.wait() # Then verify if the correct number of rules have been added. if wait_and_verify and (client_id % 5 == 0 or client_id + 1 == rule_count): current_rule_count = len(switch.dump_tables(filter_str=flow_table_filter)) try: assert current_rule_count - initial_rule_count == (client_id + 1) * 2 except: print current_rule_count, initial_rule_count, client_id raise
def low_level_start(self, pkt_count=56, pkt_size=1400, gap_ns=0, flow_count=1): """ Sends packets with low-level params. Returns a Popen handle. Avoid using this. """ f = open('./script/pktgen_wrapper_template.sh') pktgen_script = f.read() f.close() # Replace the place-holders in pktgen_wrapper.sh with actual parameters. replacement_dict = {'[PKTGEN_PROC]': self.config.pktgen_proc, '[PKTGEN_IFACE]': self.config.pktgen_iface, '[PKT_COUNT]': str(pkt_count), '[PKT_SIZE]': str(pkt_size), '[DELAY]': str(gap_ns), '[MIN_PORT]': str(Pktgen.MIN_PORT), '[MAX_PORT]': str((flow_count + Pktgen.MIN_PORT)), '[SRC_IP]': self.config.source_ip_fake, '[DST_IP]': self.config.dest_ip, '[DST_MAC]': self.config.dest_mac } pktgen_script = self._replace_string_with_dict(pktgen_script, replacement_dict) f = open('/tmp/pktgen_wrapper.sh', 'w') f.write(pktgen_script) f.close() # Copy the file to pktgen host's tmp. p = util.run_cmd('scp -q /tmp/pktgen_wrapper.sh ', 'root@', self.config.pktgen_host, ':/tmp; ', 'rm /tmp/pktgen_wrapper.sh') p.wait() # Execute the script remotely. return util.run_ssh('chmod +x /tmp/pktgen_wrapper.sh; ', 'pkill -2 pktgen_wrapper.sh; ', '/tmp/pktgen_wrapper.sh', hostname=self.config.pktgen_host)
def del_rules(self, flow_id_list, base_port_number=10000, wait_and_verify=True): """ Removes the list of flow_id rules from the flow table. """ initial_rule_count = None if wait_and_verify: initial_rule_count = len(self.dump_tables(filter="udp")) flow_id_list_copy = flow_id_list[:] while flow_id_list_copy: # Remove flows in batches of ten. ten_flow_id_list = flow_id_list_copy[0:10] flow_id_list_copy = flow_id_list_copy[10:] cmd_str = "" for flow_id in ten_flow_id_list: cmd_str += self.config.del_one_rule_cmd(flow_id + base_port_number) + "; " p = util.run_ssh(cmd_str, hostname=self.config.ofctl_ip, stdout=subprocess.PIPE, verbose=False) p.wait() sys.stdout.write("\r del_rules: %d left" % (len(flow_id_list_copy))) sys.stdout.flush() print "" if wait_and_verify: time.sleep(2) final_rule_count = len(self.dump_tables(filter="udp")) assert initial_rule_count == final_rule_count + len(flow_id_list) print "del_rules verified"