From: Itsuro ODA <oda@valinux.co.jp>
To: spp@dpdk.org
Subject: [spp] [PATCH v2 9/9] spp-ctl: spp command interface
Date: Sun, 23 Sep 2018 11:39:32 +0900 [thread overview]
Message-ID: <20180923113931.2D98.277DD91C@valinux.co.jp> (raw)
In-Reply-To: <20180923112233.2D71.277DD91C@valinux.co.jp>
From: Itsuro Oda <oda@valinux.co.jp>
Signed-off-by: Itsuro Oda <oda@valinux.co.jp>
---
src/spp-ctl/spp_proc.py | 184 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 184 insertions(+)
create mode 100644 src/spp-ctl/spp_proc.py
diff --git a/src/spp-ctl/spp_proc.py b/src/spp-ctl/spp_proc.py
new file mode 100644
index 0000000..929942a
--- /dev/null
+++ b/src/spp-ctl/spp_proc.py
@@ -0,0 +1,184 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Nippon Telegraph and Telephone Corporation
+
+import bottle
+import eventlet
+import json
+import logging
+
+import spp_ctl
+
+
+LOG = logging.getLogger(__name__)
+
+ID_PRIMARY = 0
+TYPE_PRIMARY = "primary"
+TYPE_VF = "vf"
+TYPE_NFV = "nfv"
+
+
+def exec_command(func):
+ """Define the common function of sending command & receiving reply
+ as a decorator.
+ each method for executing command has only to return command string.
+ ex.
+ @exec_command
+ def some_command(self, ...):
+ return "command string of some_command"
+ """
+ def wrapper(self, *args, **kwargs):
+ with self.sem:
+ command = func(self, *args, **kwargs)
+ LOG.info("%s(%d) command executed: %s", self.type, self.id,
+ command)
+ data = spp_ctl.Controller._send_command(self.conn, command)
+ if data is None:
+ raise RuntimeError("%s(%d): %s: no-data returned" %
+ (self.type, self.id, command))
+ LOG.debug("reply: %s", data)
+ return self._decode_reply(data)
+ return wrapper
+
+
+class SppProc(object):
+ def __init__(self, proc_type, id, conn):
+ self.id = id
+ self.type = proc_type
+ # NOTE: executing command is serialized by using a semaphore
+ # for each process.
+ self.sem = eventlet.semaphore.Semaphore(value=1)
+ self.conn = conn
+
+
+class VfProc(SppProc):
+
+ def __init__(self, id, conn):
+ super(VfProc, self).__init__(TYPE_VF, id, conn)
+
+ @staticmethod
+ def _decode_reply(data):
+ data = json.loads(data)
+ result = data["results"][0]
+ if result["result"] == "error":
+ msg = result["error_details"]["message"]
+ raise bottle.HTTPError(400, "command error: %s" % msg)
+ return data
+
+ @staticmethod
+ def _decode_client_id(data):
+ try:
+ data = VfProc._decode_reply(data)
+ return data["client_id"]
+ except:
+ return None
+
+ @exec_command
+ def get_status(self):
+ return "status"
+
+ @exec_command
+ def start_component(self, comp_name, core_id, comp_type):
+ return ("component start {comp_name} {core_id} {comp_type}"
+ .format(**locals()))
+
+ @exec_command
+ def stop_component(self, comp_name):
+ return "component stop {comp_name}".format(**locals())
+
+ @exec_command
+ def port_add(self, port, direction, comp_name, op, vlan_id, pcp):
+ command = "port add {port} {direction} {comp_name}".format(**locals())
+ if op != "none":
+ command += " %s" % op
+ if op == "add_vlantag":
+ command += " %d %d" % (vlan_id, pcp)
+ return command
+
+ @exec_command
+ def port_del(self, port, direction, comp_name):
+ return "port del {port} {direction} {comp_name}".format(**locals())
+
+ @exec_command
+ def set_classifier_table(self, mac_address, port):
+ return ("classifier_table add mac {mac_address} {port}"
+ .format(**locals()))
+
+ @exec_command
+ def clear_classifier_table(self, mac_address, port):
+ return ("classifier_table del mac {mac_address} {port}"
+ .format(**locals()))
+
+ @exec_command
+ def set_classifier_table_with_vlan(self, mac_address, port,
+ vlan_id):
+ return ("classifier_table add vlan {vlan_id} {mac_address} {port}"
+ .format(**locals()))
+
+ @exec_command
+ def clear_classifier_table_with_vlan(self, mac_address, port,
+ vlan_id):
+ return ("classifier_table del vlan {vlan_id} {mac_address} {port}"
+ .format(**locals()))
+
+
+class NfvProc(SppProc):
+
+ def __init__(self, id, conn):
+ super(NfvProc, self).__init__(TYPE_NFV, id, conn)
+
+ @staticmethod
+ def _decode_reply(data):
+ return data.strip('\0')
+
+ @staticmethod
+ def _decode_client_id(data):
+ try:
+ return int(NfvProc._decode_reply(data))
+ except:
+ return None
+
+ @exec_command
+ def get_status(self):
+ return "status"
+
+ @exec_command
+ def port_add(self, if_type, if_num):
+ return "add {if_type} {if_num}".format(**locals())
+
+ @exec_command
+ def port_del(self, if_type, if_num):
+ return "del {if_type} {if_num}".format(**locals())
+
+ @exec_command
+ def patch_add(self, src_port, dst_port):
+ return "patch {src_port} {dst_port}".format(**locals())
+
+ @exec_command
+ def patch_reset(self):
+ return "patch reset"
+
+ @exec_command
+ def forward(self):
+ return "forward"
+
+ @exec_command
+ def stop(self):
+ return "stop"
+
+
+class PrimaryProc(SppProc):
+
+ def __init__(self, conn):
+ super(PrimaryProc, self).__init__(TYPE_PRIMARY, ID_PRIMARY, conn)
+
+ @staticmethod
+ def _decode_reply(data):
+ return data.strip('\0')
+
+ @exec_command
+ def status(self):
+ return "status"
+
+ @exec_command
+ def clear(self):
+ return "clear"
--
2.17.0
--
Itsuro ODA <oda@valinux.co.jp>
prev parent reply other threads:[~2018-09-23 2:39 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-23 2:22 [spp] [PATCH v2 0/9] spp-ctl: SPP controller with Web API Itsuro ODA
2018-09-23 2:25 ` [spp] [PATCH v2 1/9] docs: overview Itsuro ODA
2018-10-02 3:29 ` Yasufumi Ogawa
2018-09-23 2:28 ` [spp] [PATCH v2 2/9] docs: api reference Itsuro ODA
2018-10-02 3:42 ` Yasufumi Ogawa
2018-10-02 4:10 ` Yasufumi Ogawa
2018-09-23 2:30 ` [spp] [PATCH v2 3/9] docs: index Itsuro ODA
2018-09-23 2:32 ` [spp] [PATCH v2 4/9] docs: top index Itsuro ODA
2018-09-23 2:33 ` [spp] PATCH v2 5/9] add requirements.txt Itsuro ODA
2018-09-23 2:35 ` [spp] [PATCH v2 6/9] spp-ctl: executable Itsuro ODA
2018-10-02 5:47 ` Yasufumi Ogawa
2018-09-23 2:36 ` [spp] [PATCH v2 7/9] spp-ctl: SPP controller with Web API Itsuro ODA
2018-09-23 2:44 ` Itsuro ODA
2018-09-25 2:01 ` Yasufumi Ogawa
2018-09-23 2:38 ` [spp] [PATCH v2 8/9] spp-ctl: web api handler Itsuro ODA
2018-10-02 4:03 ` Yasufumi Ogawa
2018-09-23 2:39 ` Itsuro ODA [this message]
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=20180923113931.2D98.277DD91C@valinux.co.jp \
--to=oda@valinux.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).