diff options
Diffstat (limited to 'scripts/dpdk_setup_ports.py')
-rwxr-xr-x | scripts/dpdk_setup_ports.py | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/scripts/dpdk_setup_ports.py b/scripts/dpdk_setup_ports.py new file mode 100755 index 00000000..8dfd742e --- /dev/null +++ b/scripts/dpdk_setup_ports.py @@ -0,0 +1,232 @@ +#! /usr/bin/python +# hhaim +import sys,site +site.addsitedir('python-lib') +import yaml +import os.path +import os +import dpdk_nic_bind +import re +import argparse; + + + +class map_driver(object): + args=None; + cfg_file='/etc/trex_cfg.yaml' + +class DpdkSetup(Exception): + pass + +class CIfMap: + + def __init__(self, cfg_file): + self.m_cfg_file =cfg_file; + self.m_cfg_dict={}; + self.m_devices={}; + + def dump_error (self,err): + s="""%s +From this TRex version a configuration file must exist in /etc/ folder " +The name of the configuration file should be /etc/trex_cfg.yaml " +The minimum configuration file should include something like this +- version : 2 # version 2 of the configuration file + interfaces : ["03:00.0","03:00.1","13:00.1","13:00.0"] # list of the interfaces to bind run ./dpdk_nic_bind.py --status to see the list + port_limit : 2 # number of ports to use valid is 2,4,6,8 + +example of already bind devices + +$ ./dpdk_nic_bind.py --status + +Network devices using DPDK-compatible driver +============================================ +0000:03:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection' drv=igb_uio unused= +0000:03:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection' drv=igb_uio unused= +0000:13:00.0 '82599ES 10-Gigabit SFI/SFP+ Network Connection' drv=igb_uio unused= +0000:13:00.1 '82599ES 10-Gigabit SFI/SFP+ Network Connection' drv=igb_uio unused= + +Network devices using kernel driver +=================================== +0000:02:00.0 '82545EM Gigabit Ethernet Controller (Copper)' if=eth2 drv=e1000 unused=igb_uio *Active* + +Other network devices +===================== + + + """ % (err); + return s; + + + def raise_error (self,err): + s= self.dump_error (err) + raise DpdkSetup(s) + + def load_config_file (self): + + fcfg=self.m_cfg_file + + if not os.path.isfile(fcfg) : + self.raise_error ("There is no valid configuration file %s " % fcfg) + + try: + stream = open(fcfg, 'r') + self.m_cfg_dict= yaml.load(stream) + except Exception,e: + print e; + raise e + + stream.close(); + + if not self.m_cfg_dict[0].has_key('version') : + self.raise_error ("Configuration file %s is old, should include version field" % fcfg ) + + if int(self.m_cfg_dict[0]['version'])<2 : + self.raise_error ("Configuration file %s is old, should include version field with value greater than 2" % fcfg) + + + if not self.m_cfg_dict[0].has_key('interfaces') : + self.raise_error ("Configuration file %s is old, should include interfaces field with 2,4,6,8 number of elemets" % fcfg) + + if_list=self.m_cfg_dict[0]['interfaces'] + if not (len(if_list) in [2,4,6,8]): + self.raise_error ("Configuration file %s should include interfaces field with 2,4,6,8 number of elemets" % fcfg) + + def do_bind_one (self,key): + cmd='./dpdk_nic_bind.py --force --bind=igb_uio %s ' % ( key) + print cmd + res=os.system(cmd); + if res!=0: + raise DpdkSetup('') + + + + def pci_name_to_full_name (self,pci_name): + c='[0-9A-Fa-f]'; + sp='[:]' + s_short=c+c+sp+c+c+'[.]'+c; + s_full=c+c+c+c+sp+s_short + re_full = re.compile(s_full) + re_short = re.compile(s_short) + + if re_short.match(pci_name): + return '0000:'+pci_name + + if re_full.match(pci_name): + return pci_name + + err=" %s is not a valid pci address \n" %pci_name; + raise DpdkSetup(err) + + + def run_dpdk_lspci (self): + dpdk_nic_bind.get_nic_details() + self.m_devices= dpdk_nic_bind.devices + + def do_run (self): + self.load_config_file () + self.run_dpdk_lspci () + + if_list=self.m_cfg_dict[0]['interfaces'] + + for obj in if_list: + key= self.pci_name_to_full_name (obj) + if not self.m_devices.has_key(key) : + err=" %s does not exist " %key; + raise DpdkSetup(err) + + + if self.m_devices[key].has_key('Driver_str'): + if self.m_devices[key]['Driver_str'] !='igb_uio' : + self.do_bind_one (key) + else: + self.do_bind_one (key) + + + def do_create (self): + print " not supported yet !" + + +def parse_parent_cfg (parent_cfg): + l=parent_cfg.split(" "); + cfg_file=''; + next=False; + for obj in l: + if next: + cfg_file=obj + next=False; + if obj == '--cfg': + next=True + + return (cfg_file) + +def process_options (): + parser = argparse.ArgumentParser(usage=""" + +Examples: +--------- + +To unbind the interfaces using the trex configuration file + dpdk_set_ports.py -l + +To create a default file + dpdk_set_ports.py -c + +To show status + dpdk_set_ports.py -s + + """, + description=" unbind dpdk interfaces ", + epilog=" written by hhaim"); + + parser.add_argument("-l", "--load", action='store_true', + help=""" unbind the interfaces using the configuration file given """, + ) + + parser.add_argument("--cfg", + help=""" configuration file name """, + ) + + parser.add_argument("--parent", + help=""" parent configuration CLI, extract --cfg from it if given """, + ) + + parser.add_argument("-c", "--create", action='store_true', + help=""" try to create a configuration file. It is heuristic try to look into the file before """, + ) + + parser.add_argument("-s", "--show", action='store_true', + help=""" show the status """, + ) + + parser.add_argument('--version', action='version', + version="0.1" ) + + map_driver.args = parser.parse_args(); + + if map_driver.args.parent : + cfg = parse_parent_cfg (map_driver.args.parent) + if cfg != '': + map_driver.cfg_file = cfg; + if map_driver.args.cfg : + map_driver.cfg_file = map_driver.args.cfg; + +def main (): + try: + process_options () + + if map_driver.args.show: + res=os.system('./dpdk_nic_bind.py --status'); + return(res); + + obj =CIfMap(map_driver.cfg_file); + + if map_driver.args.create: + obj.do_create(); + else: + obj.do_run(); + except Exception,e: + print e + exit(-1) + +main(); + |