From: x-fn-spp-ml@ntt-tx.co.jp To: ferruh.yigit@intel.com, yasufum.o@gmail.com Cc: spp@dpdk.org Subject: [spp] [PATCH 13/17] cli: add support of rte_flow in vf Date: Tue, 18 Feb 2020 15:37:16 +0900 Message-ID: <20200218063720.6597-14-x-fn-spp-ml@ntt-tx.co.jp> (raw) In-Reply-To: <20200218063720.6597-1-x-fn-spp-ml@ntt-tx.co.jp> From: Hideyuki Yamashita <yamashita.hideyuki@ntt-tx.co.jp> This patch implements support of multi-queue in vf command. - vf; status - vf; port - vf; classifier_table Signed-off-by: Hideyuki Yamashita <yamashita.hideyuki@ntt-tx.co.jp> Signed-off-by: Yasufumi Ogawa <yasufum.o@gmail.com> --- src/cli/commands/vf.py | 460 +++++++++++++++++++++++++++-------------- 1 file changed, 301 insertions(+), 159 deletions(-) diff --git a/src/cli/commands/vf.py b/src/cli/commands/vf.py index 5b361d1..c05412c 100644 --- a/src/cli/commands/vf.py +++ b/src/cli/commands/vf.py @@ -206,8 +206,8 @@ class SppVf(object): To update status of the instance of SppVf, get the status from spp-ctl. This method returns the result as a dict. For considering - behaviour of spp_vf, it is enough to return worker's name and core - IDs as the status, but might need to be update for future updates. + behaviour of spp_vf, it is enough to return worker's name, core IDs and + ports as the status, but might need to be update for future updates. # return worker's name and used core IDs, and all of core IDs. { @@ -216,12 +216,13 @@ class SppVf(object): {'name': 'mg1', 'core_id': 6}, ... ], - 'core_ids': [5, 6, 7, ...] + 'core_ids': [5, 6, 7, ...], + 'ports': ['phy:0', 'phy:1', ...] } """ - status = {'workers': [], 'core_ids': []} + status = {'workers': [], 'core_ids': [], 'ports': []} res = self.spp_ctl_cli.get('vfs/%d' % self.sec_id) if res is not None: if res.status_code == 200: @@ -236,6 +237,9 @@ class SppVf(object): 'core_id': wk['core']}) status['core_ids'].append(wk['core']) + if 'ports' in json_obj: + status['ports'] = json_obj.get('ports') + return status def _run_status(self): @@ -290,82 +294,136 @@ class SppVf(object): print('Error: unknown response.') def _run_port(self, params): - req_params = None - if len(params) == 4: - if params[0] == 'add': - action = 'attach' - elif params[0] == 'del': - action = 'detach' - else: - print('Error: Invalid action.') - return None - - req_params = {'action': action, 'port': params[1], - 'dir': params[2], - 'vlan': {'operation': 'none', - 'id': 'none', - 'pcp': 'none'}} - - elif len(params) == 5: # delete vlan with 'port add' command - # TODO(yasufum) Syntax for deleting vlan should be modified - # because deleting with 'port add' is terrible! - action = 'attach' - req_params = {'action': action, 'port': params[1], - 'dir': params[2], - 'vlan': {'operation': 'del', - 'id': 'none', - 'pcp': 'none'}} - - elif len(params) == 7: - action = 'attach' - if params[4] == 'add_vlantag': - op = 'add' - elif params[4] == 'del_vlantag': - op = 'del' - req_params = {'action': action, 'port': params[1], - 'dir': params[2], - 'vlan': {'operation': op, 'id': int(params[5]), - 'pcp': int(params[6])}} - else: - print('Error: Invalid syntax.') - - if req_params is not None: - res = self.spp_ctl_cli.put('vfs/%d/components/%s/ports' - % (self.sec_id, params[3]), req_params) - if res is not None: - error_codes = self.spp_ctl_cli.rest_common_error_codes - if res.status_code == 204: - print("Succeeded to %s port" % params[0]) - elif res.status_code in error_codes: - pass + params_index = 0 + req_params = {} + vlan_params = {} + name = None + flg_mq = False + + while params_index < len(params): + if params_index == 0: + if params[params_index] == 'add': + req_params["action"] = 'attach' + elif params[params_index] == 'del': + req_params["action"] = 'detach' else: - print('Error: unknown response.') + print('Error: Invalid action.') + return None + + elif params_index == 1: + req_params["port"] = params[params_index] + + # Check Multi queue + if params_index + 2 < len(params): + if params[params_index + 1] == "nq": + params_index += 2 + req_params["port"] += "nq" + params[params_index] + flg_mq = True + else: + print("Error: Not enough parameters.") + return None + + elif ((params_index == 2 and flg_mq is False) or + (params_index == 4 and flg_mq is True)): + req_params["dir"] = params[params_index] + + elif ((params_index == 3 and flg_mq is False) or + (params_index == 5 and flg_mq is True)): + name = params[params_index] + + elif ((params_index == 4 and flg_mq is False) or + (params_index == 6 and flg_mq is True)): + if params[params_index] == "add_vlantag": + vlan_params["operation"] = "add" + elif params[params_index] == "del_vlantag": + vlan_params["operation"] = "del" + else: + print('Error: vlantag is Only add_vlantag or del_vlantag.') + return None + + elif ((params_index == 5 and flg_mq is False) or + (params_index == 7 and flg_mq is True)): + try: + vlan_params["id"] = int(params[params_index]) + except Exception as _: + print('Error: vid is not a number.') + return None + + elif ((params_index == 6 and flg_mq is False) or + (params_index == 8 and flg_mq is True)): + try: + vlan_params["pcp"] = int(params[params_index]) + except Exception as _: + print('Error: pcp is not a number.') + return None + + params_index += 1 + + req_params["vlan"] = vlan_params + res = self.spp_ctl_cli.put('vfs/%d/components/%s/ports' + % (self.sec_id, name), req_params) + if res is not None: + error_codes = self.spp_ctl_cli.rest_common_error_codes + if res.status_code == 204: + print("Succeeded to %s port" % params[0]) + elif res.status_code in error_codes: + pass + else: + print('Error: unknown response.') def _run_cls_table(self, params): - req_params = None - if len(params) == 4: - req_params = {'action': params[0], 'type': params[1], - 'mac_address': params[2], 'port': params[3]} - - elif len(params) == 5: - req_params = {'action': params[0], 'type': params[1], - 'vlan': params[2], 'mac_address': params[3], - 'port': params[4]} - else: - print('Error: Invalid syntax.') + params_index = 0 + req_params = {} + flg_vlan = False - if req_params is not None: - req = 'vfs/%d/classifier_table' % self.sec_id - res = self.spp_ctl_cli.put(req, req_params) + # The list elements are: + # action, type, vlan, mac, port + values = [None, None, None, None, None] + values_index = 0 - if res is not None: - error_codes = self.spp_ctl_cli.rest_common_error_codes - if res.status_code == 204: - print("Succeeded to %s" % params[0]) - elif res.status_code in error_codes: - pass - else: - print('Error: unknown response.') + while params_index < len(params): + + if params_index == 0: + req_params["action"] = params[params_index] + + elif params_index == 1: + req_params["type"] = params[params_index] + if (req_params["type"] != "vlan" and + req_params["type"] != "mac"): + print("Error: Type is only vlan or mac") + return None + + elif params_index == 2 and req_params["type"] == "vlan": + req_params["vlan"] = params[params_index] + flg_vlan = True + + elif ((params_index == 2 and flg_vlan is False) or + (params_index == 3 and flg_vlan is True)): + req_params["mac_address"] = params[params_index] + + elif ((params_index == 3 and flg_vlan is False) or + (params_index == 4 and flg_vlan is True)): + req_params["port"] = params[params_index] + + # Check Multi queue + if params_index + 2 < len(params): + if params[params_index + 1] == "nq": + params_index += 2 + req_params["port"] += "nq" + params[params_index] + + params_index += 1 + + req = 'vfs/%d/classifier_table' % self.sec_id + res = self.spp_ctl_cli.put(req, req_params) + + if res is not None: + error_codes = self.spp_ctl_cli.rest_common_error_codes + if res.status_code == 204: + print("Succeeded to %s" % params[0]) + elif res.status_code in error_codes: + pass + else: + print('Error: unknown response.') def _run_exit(self): """Run `exit` command.""" @@ -411,96 +469,180 @@ class SppVf(object): return res def _compl_port(self, sub_tokens): - if len(sub_tokens) < 9: - subsub_cmds = ['add', 'del'] - res = [] - if len(sub_tokens) == 2: - for kw in subsub_cmds: - if kw.startswith(sub_tokens[1]): - res.append(kw) - elif len(sub_tokens) == 3: - if sub_tokens[1] in subsub_cmds: - if 'RES_UID'.startswith(sub_tokens[2]): - res.append('RES_UID') - elif len(sub_tokens) == 4: - if sub_tokens[1] in subsub_cmds: - for direction in ['rx', 'tx']: - if direction.startswith(sub_tokens[3]): - res.append(direction) - elif len(sub_tokens) == 5: - if sub_tokens[1] in subsub_cmds: - for kw in self.worker_names: - if kw.startswith(sub_tokens[4]): - res.append(kw) - elif len(sub_tokens) == 6: - if sub_tokens[1] == 'add': - for kw in ['add_vlantag', 'del_vlantag']: - if kw.startswith(sub_tokens[5]): - res.append(kw) - elif len(sub_tokens) == 7: - if sub_tokens[1] == 'add' and sub_tokens[5] == 'add_vlantag': - if 'VID'.startswith(sub_tokens[6]): - res.append('VID') - elif len(sub_tokens) == 8: - if sub_tokens[1] == 'add' and sub_tokens[5] == 'add_vlantag': - if 'PCP'.startswith(sub_tokens[7]): - res.append('PCP') - return res + res = [] + index = 0 + + # compl_phase "add_del" : candidate is add or del + # compl_phase "res_uid" : candidate is RES_UID + # compl_phase "nq" : candidate is nq + # compl_phase "queue_no" : candidate is queue no + # compl_phase "dir" : candidate is DIR + # compl_phase "name" : candidate is NAME + # compl_phase "vlan_tag" : candidate is vlan tag + # compl_phase "vid" : candidate is vid + # compl_phase "pcp" : candidate is pcp + # compl_phase None : candidate is None + compl_phase = "add_del" + add_or_del = None + + while index < len(sub_tokens): + if compl_phase == "nq": + queue_no_list = self._get_candidate_phy_queue_no( + sub_tokens[index - 1]) + + if queue_no_list is None: + compl_phase = "dir" + + if ((compl_phase == "add_del") and + (sub_tokens[index - 1] == "port")): + res = ["add", "del"] + compl_phase = "res_uid" + + elif ((compl_phase == "res_uid") and + (sub_tokens[index - 1] == "add" or + sub_tokens[index - 1] == "del")): + res = ["RES_UID"] + compl_phase = "nq" + add_or_del = sub_tokens[index - 1] + + elif compl_phase == "nq": + res = ["nq"] + compl_phase = "queue_no" + + elif compl_phase == "queue_no": + res = queue_no_list + compl_phase = "dir" + + elif compl_phase == "dir": + res = ["rx", "tx"] + compl_phase = "name" + + elif compl_phase == "name": + res = ["NAME"] + if add_or_del == "add": + compl_phase = "vlan_tag" + else: + compl_phase = None + + elif compl_phase == "vlan_tag": + res = ["add_vlantag", "del_vlantag"] + compl_phase = "vid" + + elif (compl_phase == "vid" and + sub_tokens[index - 1] == "add_vlantag"): + res = ["VID"] + compl_phase = "pcp" + + elif compl_phase == "pcp": + res = ["PCP"] + compl_phase = None + + else: + res = [] + + index += 1 + + res = [p for p in res + if p.startswith(sub_tokens[len(sub_tokens) - 1])] + + return res + + def _get_candidate_phy_queue_no(self, res_uid): + """Get phy queue_no candidate. + If res_uid is phy and multi-queue, return queue_no in list type. + Otherwise returns None. + """ + + try: + port, _ = res_uid.split(":") + except Exception as _: + return None + + if port != "phy": + return None + + status = self._get_status(self.sec_id) + + queue_no_list = [] + for port in status["ports"]: + if not port.startswith(res_uid): + continue + + try: + _, queue_no = port.split("nq") + except Exception as _: + continue + + queue_no_list.append(queue_no.strip(" ")) + + if len(queue_no_list) == 0: + return None + + return queue_no_list def _compl_cls_table(self, sub_tokens): - if len(sub_tokens) < 7: - subsub_cmds = ['add', 'del'] - res = [] + res = [] + index = 0 + + # compl_phase "add_del" : candidate is add or del + # compl_phase "vlan_mac" : candidate is vlan or mac + # compl_phase "vid" : candidate is VID + # compl_phase "mac_addr" : candidate is MAC_ADDR or default + # compl_phase "res_uid" : candidate is RES_UID + # compl_phase "nq" : candidate is nq + # compl_phase "queue_no" : candidate is queue_no + # compl_phase None : candidate is None + compl_phase = "add_del" + + while index < len(sub_tokens): + + if compl_phase == "vid" and sub_tokens[index - 1] == "mac": + compl_phase = "mac_addr" + + if compl_phase == "nq": + queue_no_list = self._get_candidate_phy_queue_no( + sub_tokens[index - 1]) + if queue_no_list is None: + compl_phase = None + + if ((compl_phase == "add_del") and + (sub_tokens[index - 1] == "classifier_table")): + res = ["add", "del"] + compl_phase = "vlan_mac" + + elif compl_phase == "vlan_mac": + res = ["vlan", "mac"] + compl_phase = "vid" + + elif compl_phase == "vid" and sub_tokens[index - 1] == "vlan": + res = ["VID"] + compl_phase = "mac_addr" + + elif compl_phase == "mac_addr": + res = ["MAC_ADDR", "default"] + compl_phase = "res_uid" + + elif compl_phase == "res_uid": + res = ["RES_UID"] + compl_phase = "nq" + + elif compl_phase == "nq": + res = ["nq"] + compl_phase = "queue_no" + + elif compl_phase == "queue_no": + res = queue_no_list + compl_phase = None - if len(sub_tokens) == 2: - for kw in subsub_cmds: - if kw.startswith(sub_tokens[1]): - res.append(kw) + else: + res = [] - elif len(sub_tokens) == 3: - if sub_tokens[1] in subsub_cmds: - for kw in ['mac', 'vlan']: - if kw.startswith(sub_tokens[2]): - res.append(kw) + index += 1 - elif len(sub_tokens) == 4: - if sub_tokens[1] == 'add': - if sub_tokens[2] == 'mac': - if 'MAC_ADDR'.startswith(sub_tokens[3]): - res.append('MAC_ADDR') - elif sub_tokens[2] == 'vlan': - if 'VID'.startswith('VID'): - res.append('VID') - elif sub_tokens[1] == 'del': - if sub_tokens[2] == 'mac': - if 'MAC_ADDR'.startswith(sub_tokens[3]): - res.append('MAC_ADDR') - if sub_tokens[2] == 'vlan': - if 'VID'.startswith(sub_tokens[3]): - res.append('VID') + res = [p for p in res + if p.startswith(sub_tokens[len(sub_tokens) - 1])] - elif len(sub_tokens) == 5: - if sub_tokens[1] == 'add': - if sub_tokens[2] == 'mac': - if 'RES_UID'.startswith(sub_tokens[4]): - res.append('RES_UID') - elif sub_tokens[2] == 'vlan': - if 'MAC_ADDR'.startswith(sub_tokens[4]): - res.append('MAC_ADDR') - if sub_tokens[1] == 'del': - if sub_tokens[2] == 'mac': - if 'RES_UID'.startswith(sub_tokens[4]): - res.append('RES_UID') - elif sub_tokens[2] == 'vlan': - if 'MAC_ADDR'.startswith(sub_tokens[4]): - res.append('MAC_ADDR') - - elif len(sub_tokens) == 6: - if sub_tokens[1] in subsub_cmds and \ - sub_tokens[2] == 'vlan': - if 'RES_UID'.startswith(sub_tokens[5]): - res.append('RES_UID') - return res + return res @classmethod def help(cls): -- 2.17.1
next prev parent reply other threads:[~2020-02-18 6:37 UTC|newest] Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-02-18 6:37 [spp] [PATCH 00/17] Adding Hardware offload capability x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 01/17] shared: add support of multi-queue x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 02/17] spp_vf: " x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 03/17] spp_mirror: " x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 04/17] spp_pcap: " x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 05/17] spp_primary: " x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 06/17] spp_primary: add support of rte_flow x-fn-spp-ml 2020-02-19 2:24 ` Yasufumi Ogawa 2020-02-19 11:57 ` [spp] (x-fn-spp-ml 118) " Hideyuki Yamashita 2020-02-18 6:37 ` [spp] [PATCH 07/17] spp_primary: add common function " x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 08/17] spp_primary: add attribute " x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 09/17] spp_primary: add patterns " x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 10/17] spp_primary: add actions " x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 11/17] bin: add parameter for hardrare offload x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 12/17] cli: add support of hardware offload x-fn-spp-ml 2020-02-18 6:37 ` x-fn-spp-ml [this message] 2020-02-18 6:37 ` [spp] [PATCH 14/17] cli: add support of rte_flow in mirror x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 15/17] cli: add support of rte_flow in nfv x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 16/17] spp-ctl: add APIs for flow rules x-fn-spp-ml 2020-02-18 6:37 ` [spp] [PATCH 17/17] spp_nfv: add support of multi-queue x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 00/17] Adding Hardware offload capability x-fn-spp-ml 2020-02-21 8:17 ` Yasufumi Ogawa 2020-02-25 5:49 ` [spp] (x-fn-spp-ml 177) " Hideyuki Yamashita 2020-02-19 11:49 ` [spp] [PATCH v2 01/17] shared: add support of multi-queue x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 02/17] spp_vf: " x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 03/17] spp_mirror: " x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 04/17] spp_pcap: " x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 05/17] spp_primary: " x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 06/17] spp_primary: add support of rte_flow x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 07/17] spp_primary: add common function " x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 08/17] spp_primary: add attribute " x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 09/17] spp_primary: add patterns " x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 10/17] spp_primary: add actions " x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 11/17] bin: add parameter for hardrare offload x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 12/17] cli: add support of hardware offload x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 13/17] cli: add support of rte_flow in vf x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 14/17] cli: add support of rte_flow in mirror x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 15/17] cli: add support of rte_flow in nfv x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 16/17] spp-ctl: add APIs for flow rules x-fn-spp-ml 2020-02-19 11:49 ` [spp] [PATCH v2 17/17] spp_nfv: add support of multi-queue x-fn-spp-ml
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=20200218063720.6597-14-x-fn-spp-ml@ntt-tx.co.jp \ --to=x-fn-spp-ml@ntt-tx.co.jp \ --cc=ferruh.yigit@intel.com \ --cc=spp@dpdk.org \ --cc=yasufum.o@gmail.com \ /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
Soft Patch Panel This inbox may be cloned and mirrored by anyone: git clone --mirror https://inbox.dpdk.org/spp/0 spp/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 spp spp/ https://inbox.dpdk.org/spp \ spp@dpdk.org public-inbox-index spp Example config snippet for mirrors. Newsgroup available over NNTP: nntp://inbox.dpdk.org/inbox.dpdk.spp AGPL code for this site: git clone https://public-inbox.org/public-inbox.git