From: x-fn-spp@sl.ntt-tx.co.jp
To: ferruh.yigit@intel.com, ogawa.yasufumi@lab.ntt.co.jp
Cc: spp@dpdk.org
Subject: [spp] [PATCH v2 6/7] controller: add SppPcap class
Date: Fri, 8 Feb 2019 17:44:37 +0900 [thread overview]
Message-ID: <201902080844.x188icKv030833@imss04.silk.ntt-tx.co.jp> (raw)
In-Reply-To: <20190208084438.7952-1-x-fn-spp@sl.ntt-tx.co.jp>
From: Hideyuki Yamashita <yamashita.hideyuki@po.ntt-tx.co.jp>
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 <yamashita.hideyuki@po.ntt-tx.co.jp>
Signed-off-by: Naoki Takada <takada.naoki@lab.ntt.co.jp>
---
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
next prev parent reply other threads:[~2019-02-08 8:46 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20190208084438.7952-1-x-fn-spp@sl.ntt-tx.co.jp>
2019-02-08 8:44 ` [spp] [PATCH v2 1/7] spp_pcap: add command main x-fn-spp
2019-02-08 8:44 ` [spp] [PATCH v2 2/7] spp_pcap: add command decode x-fn-spp
2019-02-08 8:44 ` [spp] [PATCH v2 3/7] spp_pcap: add management function x-fn-spp
2019-02-08 8:44 ` [spp] [PATCH v2 4/7] spp_pcap: add spp_pcap main function x-fn-spp
2019-02-08 8:44 ` [spp] [PATCH v2 5/7] spp_pcap: add Makefile for spp_pcap x-fn-spp
2019-02-08 8:44 ` x-fn-spp [this message]
2019-02-08 8:44 ` [spp] [PATCH v2 7/7] controller: add pcap command to SPP controller x-fn-spp
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201902080844.x188icKv030833@imss04.silk.ntt-tx.co.jp \
--to=x-fn-spp@sl.ntt-tx.co.jp \
--cc=ferruh.yigit@intel.com \
--cc=ogawa.yasufumi@lab.ntt.co.jp \
--cc=spp@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).