From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail04.ics.ntt-tx.co.jp (mail05.ics.ntt-tx.co.jp [210.232.35.69]) by dpdk.org (Postfix) with ESMTP id AF5421B4E3 for ; Fri, 8 Feb 2019 09:46:00 +0100 (CET) Received: from gwchk03.silk.ntt-tx.co.jp (gwchk03.silk.ntt-tx.co.jp [10.107.0.111]) by mail04.ics.ntt-tx.co.jp (unknown) with ESMTP id x188jxip009007; Fri, 8 Feb 2019 17:45:59 +0900 Received: (from root@localhost) by gwchk03.silk.ntt-tx.co.jp (unknown) id x188jxUP025849; Fri, 8 Feb 2019 17:45:59 +0900 Received: from gwchk.silk.ntt-tx.co.jp [10.107.0.110] by gwchk03.silk.ntt-tx.co.jp with ESMTP id TAA25076; Fri, 8 Feb 2019 17:44:38 +0900 Received: from imss04.silk.ntt-tx.co.jp (localhost [127.0.0.1]) by imss04.silk.ntt-tx.co.jp (unknown) with ESMTP id x188iccU030838; Fri, 8 Feb 2019 17:44:38 +0900 Received: from mgate02.silk.ntt-tx.co.jp (smtp02.silk.ntt-tx.co.jp [10.107.0.37]) by imss04.silk.ntt-tx.co.jp (unknown) with ESMTP id x188icKv030833; Fri, 8 Feb 2019 17:44:38 +0900 Message-Id: <201902080844.x188icKv030833@imss04.silk.ntt-tx.co.jp> Received: from localhost by mgate02.silk.ntt-tx.co.jp (unknown) id x188icg3028979 ; Fri, 8 Feb 2019 17:44:38 +0900 From: x-fn-spp@sl.ntt-tx.co.jp To: ferruh.yigit@intel.com, ogawa.yasufumi@lab.ntt.co.jp Cc: spp@dpdk.org Date: Fri, 8 Feb 2019 17:44:37 +0900 X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190208084438.7952-1-x-fn-spp@sl.ntt-tx.co.jp> References: <20190208084438.7952-1-x-fn-spp@sl.ntt-tx.co.jp> X-TM-AS-MML: No Subject: [spp] [PATCH v2 6/7] controller: add SppPcap class X-BeenThere: spp@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Soft Patch Panel List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Feb 2019 08:46:01 -0000 From: Hideyuki Yamashita This update is to add SppPcap class behaviour as a client for spp-ctl. An instance of the class is intended to be used from do_pcap() and complete_pcap() methods of Shell class in 'spp.py'. Signed-off-by: Hideyuki Yamashita Signed-off-by: Naoki Takada --- src/controller/commands/pcap.py | 230 ++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 src/controller/commands/pcap.py diff --git a/src/controller/commands/pcap.py b/src/controller/commands/pcap.py new file mode 100644 index 0000000..89a1a5f --- /dev/null +++ b/src/controller/commands/pcap.py @@ -0,0 +1,230 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2019 Nippon Telegraph and Telephone Corporation + + +class SppPcap(object): + """Exec spp_pcap command. + + SppPcap class is intended to be used in Shell class as a delegator + for running 'pcap' command. + + 'self.command()' is called from do_pcap() and 'self.complete()' is called + from complete_() of both of which is defined in Shell. + """ + + # All of commands and sub-commands used for validation and completion. + PCAP_CMDS = { + 'status': None, + 'start': None, + 'stop': None, + 'exit': None} + + WORKER_TYPES = ['receive', 'write'] + + def __init__(self, spp_ctl_cli, sec_id, use_cache=False): + self.spp_ctl_cli = spp_ctl_cli + self.sec_id = sec_id + + # Update 'self.worker_names' and 'self.unused_core_ids' each time + # 'self.run()' is called if it is 'False'. + # True to 'True' if you do not wait for spp_pcap's response. + self.use_cache = use_cache + + # Names and core IDs of worker threads + pcap_status = self._get_status(self.sec_id) + + core_ids = pcap_status['core_ids'] + for wk in pcap_status['workers']: + if wk['core_id'] in core_ids: + core_ids.remove(wk['core_id']) + self.unused_core_ids = core_ids # used while completion to exclude + + self.workers = pcap_status['workers'] + self.worker_names = [attr['role'] for attr in pcap_status['workers']] + + def run(self, cmdline): + """Called from do_sec() to Send command to secondary process.""" + + # update status each time if configured not to use cache + if self.use_cache is False: + pcap_status = self._get_status(self.sec_id) + + core_ids = pcap_status['core_ids'] + for wk in pcap_status['workers']: + if wk['core_id'] in core_ids: + core_ids.remove(wk['core_id']) + self.unused_core_ids = core_ids # used while completion to exclude + + self.workers = pcap_status['workers'] + self.worker_names = [attr['role'] + for attr in pcap_status['workers']] + + cmd = cmdline.split(' ')[0] + params = cmdline.split(' ')[1:] + + if cmd == 'status': + res = self.spp_ctl_cli.get('pcaps/%d' % self.sec_id) + if res is not None: + error_codes = self.spp_ctl_cli.rest_common_error_codes + if res.status_code == 200: + self.print_status(res.json()) + elif res.status_code in error_codes: + pass + else: + print('Error: unknown response.') + + elif cmd == 'start': + req_params = {'action': 'start'} + res = self.spp_ctl_cli.put('pcaps/%d/capture' + % (self.sec_id), req_params) + if res is not None: + error_codes = self.spp_ctl_cli.rest_common_error_codes + if res.status_code == 204: + print("Start packet capture.") + elif res.status_code in error_codes: + pass + else: + print('Error: unknown response.') + + elif cmd == 'stop': + req_params = {'action': 'stop'} + res = self.spp_ctl_cli.put('pcaps/%d/capture' + % (self.sec_id), req_params) + if res is not None: + error_codes = self.spp_ctl_cli.rest_common_error_codes + if res.status_code == 204: + print("Stop packet capture.") + elif res.status_code in error_codes: + pass + else: + print('Error: unknown response.') + + elif cmd == 'exit': + res = self.spp_ctl_cli.delete('pcaps/%d' % (self.sec_id)) + if res is not None: + error_codes = self.spp_ctl_cli.rest_common_error_codes + if res.status_code == 204: + print("Exit pcap %d." % (self.sec_id)) + elif res.status_code in error_codes: + pass + else: + print('Error: unknown response.') + + else: + print('Invalid command "%s".' % cmd) + + def print_status(self, json_obj): + """Parse and print message from SPP PCAP. + + Print status received from spp_pcap. + + spp > pcap 1; status + - client-id: 3 + - satus: running + - core:2, receive + - rx: phy:0 + - core:3, write + - file: /tmp/spp_pcap.20181108110600.phy0.1.1.pcap + - core:4, write + - file: /tmp/spp_pcap.20181108110600.phy0.2.1.pcap + - core:5, write + - file: /tmp/spp_pcap.20181108110600.phy0.3.1.pcap + ... + + """ + + # client id and status + print(' - client-id: %d' % json_obj['client-id']) + print(' - status: %s' % json_obj['status']) + + # Core + for worker in json_obj['core']: + if 'role' in worker.keys(): + print(" - core:%d %s" % ( + worker['core'], worker['role'])) + + if worker['role'] == 'receive': + pt = worker['rx_port'][0]['port'] + msg = ' - %s:%s' + print(msg % ('rx', pt)) + else: + print(' - filename: %s' % worker['filename']) + + def complete(self, sec_ids, text, line, begidx, endidx): + """Completion for spp_pcap commands. + + Called from complete_pcap() to complete. + """ + + try: + completions = [] + tokens = line.split(';') + + if len(tokens) == 2: + sub_tokens = tokens[1].split(' ') + + if len(sub_tokens) == 1: + if not (sub_tokens[0] in self.PCAP_CMDS.keys()): + completions = self._compl_first_tokens(sub_tokens[0]) + else: + if sub_tokens[0] == 'status': + if len(sub_tokens) < 2: + if 'status'.startswith(sub_tokens[1]): + completions = ['status'] + + elif sub_tokens[0] == 'start': + if len(sub_tokens) < 2: + if 'start'.startswith(sub_tokens[1]): + completions = ['start'] + + elif sub_tokens[0] == 'stop': + if len(sub_tokens) < 2: + if 'stop'.startswith(sub_tokens[1]): + completions = ['stop'] + return completions + except Exception as e: + print(e) + + def _compl_first_tokens(self, token): + res = [] + for kw in self.PCAP_CMDS.keys(): + if kw.startswith(token): + res.append(kw) + return res + + def _get_status(self, sec_id): + """Get status of spp_pcap. + + To update status of the instance of SppPcap, get the status from + spp-ctl. This method returns the result as a dict. For considering + behaviour of spp_pcap, it is enough to return worker's name and core + IDs as the status, but might need to be update for future updates. + + # return worker's role and used core IDs, and all of core IDs. + { + 'workers': [ + {'role': 'receive', 'core_id': 5}, + {'role': 'write', 'core_id': 6}, + ... + ], + 'core_ids': [5, 6, 7, ...] + } + + """ + + status = {'workers': [], 'core_ids': []} + res = self.spp_ctl_cli.get('pcaps/%d' % self.sec_id) + if res is not None: + if res.status_code == 200: + json_obj = res.json() + + if 'core' in json_obj.keys(): + for wk in json_obj['core']: + if 'core' in wk.keys(): + if 'role' in wk.keys(): + status['workers'].append( + {'role': wk['role'], + 'core_id': wk['core']}) + status['core_ids'].append(wk['core']) + + return status -- 2.17.1