get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/132831/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 132831,
    "url": "http://patches.dpdk.org/api/patches/132831/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20231018063347.68081-3-skori@marvell.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20231018063347.68081-3-skori@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231018063347.68081-3-skori@marvell.com",
    "date": "2023-10-18T06:33:37",
    "name": "[v9,02/12] app/graph: support telnet connectivity framework",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "37e46f147badef6122e1b3e0a504b829c7eb2d1c",
    "submitter": {
        "id": 1318,
        "url": "http://patches.dpdk.org/api/people/1318/?format=api",
        "name": "Sunil Kumar Kori",
        "email": "skori@marvell.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20231018063347.68081-3-skori@marvell.com/mbox/",
    "series": [
        {
            "id": 29897,
            "url": "http://patches.dpdk.org/api/series/29897/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=29897",
            "date": "2023-10-18T06:33:35",
            "name": "add CLI based graph application",
            "version": 9,
            "mbox": "http://patches.dpdk.org/series/29897/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/132831/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/132831/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id EE9AC43196;\n\tWed, 18 Oct 2023 08:34:07 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id D628240E6E;\n\tWed, 18 Oct 2023 08:34:00 +0200 (CEST)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173])\n by mails.dpdk.org (Postfix) with ESMTP id 505D0406B7\n for <dev@dpdk.org>; Wed, 18 Oct 2023 08:33:58 +0200 (CEST)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id\n 39I3upEU018791 for <dev@dpdk.org>; Tue, 17 Oct 2023 23:33:57 -0700",
            "from dc5-exch01.marvell.com ([199.233.59.181])\n by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3tstb3uqdj-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n for <dev@dpdk.org>; Tue, 17 Oct 2023 23:33:57 -0700",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH01.marvell.com\n (10.69.176.38) with Microsoft SMTP Server (TLS) id 15.0.1497.48;\n Tue, 17 Oct 2023 23:33:55 -0700",
            "from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend\n Transport; Tue, 17 Oct 2023 23:33:54 -0700",
            "from localhost.localdomain (unknown [10.28.34.25])\n by maili.marvell.com (Postfix) with ESMTP id BBF093F7048;\n Tue, 17 Oct 2023 23:33:53 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-transfer-encoding : content-type; s=pfpt0220;\n bh=OLEjH3Uj6J4egWP24lwxVvkn4uEq+5Qj6Z2S6xledt4=;\n b=CaybZu2I2q1HqlwNAjv0lanysPNKWz+BbzEaI4DkF1k2WSBfnsE10p1fAB4r0RVAz1kI\n DuCgXDY5n80h3+nteZq9Vf8LPTjVs1rwwUih4B31GMi+aX7L+wgLnc5hQTX5Gvw7UhCH\n 2xI0dY7N0JBDRJThGUPFdMk3/eBaffji7oToJ2ThlXSMv+rxBJhD97iYryMM4OR+n+sB\n PEKDCWUS8KhftiQF+rmh4FBrXHdyHLo9oTnz9EsbGWhR3db5KoKdFnSslDztWr2QC9MK\n sKsEZ9Z8cXx8ma8TiT2tej/lrety9S2mcNhG/JjfpW80BnNTjcgiquZJrXkJVXmsRDwx WQ==",
        "From": "<skori@marvell.com>",
        "To": "Sunil Kumar Kori <skori@marvell.com>, Rakesh Kudurumalla\n <rkudurumalla@marvell.com>",
        "CC": "<dev@dpdk.org>, Jerin Jacob <jerinj@marvell.com>",
        "Subject": "[PATCH v9 02/12] app/graph: support telnet connectivity framework",
        "Date": "Wed, 18 Oct 2023 12:03:37 +0530",
        "Message-ID": "<20231018063347.68081-3-skori@marvell.com>",
        "X-Mailer": "git-send-email 2.25.1",
        "In-Reply-To": "<20231018063347.68081-1-skori@marvell.com>",
        "References": "<20230929095814.692890-2-skori@marvell.com>\n <20231018063347.68081-1-skori@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-ORIG-GUID": "czzpnBbnS8r9QTDTbBcJ5ATz6zZoN-lZ",
        "X-Proofpoint-GUID": "czzpnBbnS8r9QTDTbBcJ5ATz6zZoN-lZ",
        "X-Proofpoint-Virus-Version": "vendor=baseguard\n engine=ICAP:2.0.272,Aquarius:18.0.980,Hydra:6.0.619,FMLib:17.11.176.26\n definitions=2023-10-18_03,2023-10-17_01,2023-05-22_02",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.29",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "From: Sunil Kumar Kori <skori@marvell.com>\n\nAdds framework to initiate a telnet session with application.\n\nSome configurations and debug commands are exposed as runtime APIs.\nThose commands can be invoked using telnet session.\n\nApplication initiates a telnet server with host address 0.0.0.0\nand port number 8086 by default.\n\nTo make it configurable, \"-h\" and \"-p\" options are provided.\nUsing them user can pass host address and port number on which\napplication will start telnet server.\n\nUsing same host address and port number, telnet client can connect\nto application.\n\nSyntax to connect with application:\n\t# telnet <host> <port>\n\nOnce session is connected, \"graph> \" prompt will be available.\nExample:\n\t# telnet 10.28.35.207 50000\n\t  Trying 10.28.35.207...\n\t  Connected to 10.28.35.207.\n\t  Escape character is '^]'.\n\n\t  Welcome!\n\n\t  graph>\n\nSigned-off-by: Sunil Kumar Kori <skori@marvell.com>\nSigned-off-by: Rakesh Kudurumalla <rkudurumalla@marvell.com>\nAcked-by: Jerin Jacob <jerinj@marvell.com>\n---\n app/graph/conn.c           | 284 +++++++++++++++++++++++++++++++++++++\n app/graph/conn.h           |  46 ++++++\n app/graph/main.c           | 103 +++++++++++++-\n app/graph/meson.build      |   1 +\n app/graph/module_api.h     |   3 +\n doc/guides/tools/graph.rst |  38 +++++\n 6 files changed, 470 insertions(+), 5 deletions(-)\n create mode 100644 app/graph/conn.c\n create mode 100644 app/graph/conn.h",
    "diff": "diff --git a/app/graph/conn.c b/app/graph/conn.c\nnew file mode 100644\nindex 0000000000..44934602c7\n--- /dev/null\n+++ b/app/graph/conn.c\n@@ -0,0 +1,284 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Marvell.\n+ */\n+\n+#include <arpa/inet.h>\n+#include <errno.h>\n+#include <netinet/in.h>\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <string.h>\n+#include <sys/epoll.h>\n+#include <sys/socket.h>\n+#include <sys/types.h>\n+#include <unistd.h>\n+\n+#include <rte_string_fns.h>\n+\n+#include \"module_api.h\"\n+\n+#define MSG_CMD_TOO_LONG \"Command too long.\"\n+\n+static int\n+data_event_handle(struct conn *conn, int fd_client)\n+{\n+\tssize_t len, i, rc = 0;\n+\n+\t/* Read input message */\n+\tlen = read(fd_client, conn->buf, conn->buf_size);\n+\tif (len == -1) {\n+\t\tif ((errno == EAGAIN) || (errno == EWOULDBLOCK))\n+\t\t\treturn 0;\n+\n+\t\treturn -1;\n+\t}\n+\n+\tif (len == 0)\n+\t\treturn rc;\n+\n+\t/* Handle input messages */\n+\tfor (i = 0; i < len; i++) {\n+\t\tif (conn->buf[i] == '\\n') {\n+\t\t\tsize_t n;\n+\n+\t\t\tconn->msg_in[conn->msg_in_len] = 0;\n+\t\t\tconn->msg_out[0] = 0;\n+\n+\t\t\tconn->msg_handle(conn->msg_in, conn->msg_out, conn->msg_out_len_max,\n+\t\t\t\t\t conn->msg_handle_arg);\n+\n+\t\t\tn = strlen(conn->msg_out);\n+\t\t\tif (n) {\n+\t\t\t\trc = write(fd_client, conn->msg_out, n);\n+\t\t\t\tif (rc == -1)\n+\t\t\t\t\tgoto exit;\n+\t\t\t}\n+\n+\t\t\tconn->msg_in_len = 0;\n+\t\t} else if (conn->msg_in_len < conn->msg_in_len_max) {\n+\t\t\tconn->msg_in[conn->msg_in_len] = conn->buf[i];\n+\t\t\tconn->msg_in_len++;\n+\t\t} else {\n+\t\t\trc = write(fd_client, MSG_CMD_TOO_LONG, strlen(MSG_CMD_TOO_LONG));\n+\t\t\tif (rc == -1)\n+\t\t\t\tgoto exit;\n+\n+\t\t\tconn->msg_in_len = 0;\n+\t\t}\n+\t}\n+\n+\t/* Write prompt */\n+\trc = write(fd_client, conn->prompt, strlen(conn->prompt));\n+\trc = (rc == -1) ? -1 : 0;\n+\n+exit:\n+\treturn rc;\n+}\n+\n+static int\n+control_event_handle(struct conn *conn, int fd_client)\n+{\n+\tint rc;\n+\n+\trc = epoll_ctl(conn->fd_client_group, EPOLL_CTL_DEL, fd_client, NULL);\n+\tif (rc == -1)\n+\t\tgoto exit;\n+\n+\trc = close(fd_client);\n+\tif (rc == -1)\n+\t\tgoto exit;\n+\n+\trc = 0;\n+\n+exit:\n+\treturn rc;\n+}\n+\n+struct conn *\n+conn_init(struct conn_params *p)\n+{\n+\tint fd_server, fd_client_group, rc;\n+\tstruct sockaddr_in server_address;\n+\tstruct conn *conn = NULL;\n+\tint reuse = 1;\n+\n+\tmemset(&server_address, 0, sizeof(server_address));\n+\n+\t/* Check input arguments */\n+\tif ((p == NULL) || (p->welcome == NULL) || (p->prompt == NULL) || (p->addr == NULL) ||\n+\t    (p->buf_size == 0) || (p->msg_in_len_max == 0) || (p->msg_out_len_max == 0) ||\n+\t    (p->msg_handle == NULL))\n+\t\tgoto exit;\n+\n+\trc = inet_aton(p->addr, &server_address.sin_addr);\n+\tif (rc == 0)\n+\t\tgoto exit;\n+\n+\t/* Memory allocation */\n+\tconn = calloc(1, sizeof(struct conn));\n+\tif (conn == NULL)\n+\t\tgoto exit;\n+\n+\tconn->welcome = calloc(1, CONN_WELCOME_LEN_MAX + 1);\n+\tconn->prompt = calloc(1, CONN_PROMPT_LEN_MAX + 1);\n+\tconn->buf = calloc(1, p->buf_size);\n+\tconn->msg_in = calloc(1, p->msg_in_len_max + 1);\n+\tconn->msg_out = calloc(1, p->msg_out_len_max + 1);\n+\n+\tif ((conn->welcome == NULL) || (conn->prompt == NULL) || (conn->buf == NULL) ||\n+\t    (conn->msg_in == NULL) || (conn->msg_out == NULL)) {\n+\t\tconn_free(conn);\n+\t\tconn = NULL;\n+\t\tgoto exit;\n+\t}\n+\n+\t/* Server socket */\n+\tserver_address.sin_family = AF_INET;\n+\tserver_address.sin_port = htons(p->port);\n+\n+\tfd_server = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);\n+\tif (fd_server == -1) {\n+\t\tconn_free(conn);\n+\t\tconn = NULL;\n+\t\tgoto exit;\n+\t}\n+\n+\tif (setsockopt(fd_server, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse,\n+\t\t       sizeof(reuse)) < 0)\n+\t\tgoto free;\n+\n+\trc = bind(fd_server, (struct sockaddr *)&server_address, sizeof(server_address));\n+\tif (rc == -1)\n+\t\tgoto free;\n+\n+\trc = listen(fd_server, 16);\n+\tif (rc == -1)\n+\t\tgoto free;\n+\n+\t/* Client group */\n+\tfd_client_group = epoll_create(1);\n+\tif (fd_client_group == -1)\n+\t\tgoto free;\n+\n+\t/* Fill in */\n+\trte_strscpy(conn->welcome, p->welcome, CONN_WELCOME_LEN_MAX);\n+\trte_strscpy(conn->prompt, p->prompt, CONN_PROMPT_LEN_MAX);\n+\tconn->buf_size = p->buf_size;\n+\tconn->msg_in_len_max = p->msg_in_len_max;\n+\tconn->msg_out_len_max = p->msg_out_len_max;\n+\tconn->msg_in_len = 0;\n+\tconn->fd_server = fd_server;\n+\tconn->fd_client_group = fd_client_group;\n+\tconn->msg_handle = p->msg_handle;\n+\tconn->msg_handle_arg = p->msg_handle_arg;\n+\n+exit:\n+\treturn conn;\n+free:\n+\tconn_free(conn);\n+\tclose(fd_server);\n+\tconn = NULL;\n+\treturn conn;\n+}\n+\n+void\n+conn_free(struct conn *conn)\n+{\n+\tif (conn == NULL)\n+\t\treturn;\n+\n+\tif (conn->fd_client_group)\n+\t\tclose(conn->fd_client_group);\n+\n+\tif (conn->fd_server)\n+\t\tclose(conn->fd_server);\n+\n+\tfree(conn->msg_out);\n+\tfree(conn->msg_in);\n+\tfree(conn->prompt);\n+\tfree(conn->welcome);\n+\tfree(conn);\n+}\n+\n+int\n+conn_req_poll(struct conn *conn)\n+{\n+\tstruct sockaddr_in client_address;\n+\tsocklen_t client_address_length;\n+\tstruct epoll_event event;\n+\tint fd_client, rc;\n+\n+\t/* Check input arguments */\n+\tif (conn == NULL)\n+\t\treturn -1;\n+\n+\t/* Server socket */\n+\tclient_address_length = sizeof(client_address);\n+\tfd_client = accept4(conn->fd_server, (struct sockaddr *)&client_address,\n+\t\t\t    &client_address_length, SOCK_NONBLOCK);\n+\tif (fd_client == -1) {\n+\t\tif ((errno == EAGAIN) || (errno == EWOULDBLOCK))\n+\t\t\treturn 0;\n+\n+\t\treturn -1;\n+\t}\n+\n+\t/* Client group */\n+\tevent.events = EPOLLIN | EPOLLRDHUP | EPOLLHUP;\n+\tevent.data.fd = fd_client;\n+\n+\trc = epoll_ctl(conn->fd_client_group, EPOLL_CTL_ADD, fd_client, &event);\n+\tif (rc == -1) {\n+\t\tclose(fd_client);\n+\t\tgoto exit;\n+\t}\n+\n+\t/* Client */\n+\trc = write(fd_client, conn->welcome, strlen(conn->welcome));\n+\tif (rc == -1) {\n+\t\tclose(fd_client);\n+\t\tgoto exit;\n+\t}\n+\n+\trc = write(fd_client, conn->prompt, strlen(conn->prompt));\n+\tif (rc == -1) {\n+\t\tclose(fd_client);\n+\t\tgoto exit;\n+\t}\n+\n+\trc = 0;\n+\n+exit:\n+\treturn rc;\n+}\n+\n+int\n+conn_msg_poll(struct conn *conn)\n+{\n+\tint fd_client, rc, rc_data = 0, rc_control = 0;\n+\tstruct epoll_event event;\n+\n+\t/* Check input arguments */\n+\tif (conn == NULL)\n+\t\treturn -1;\n+\n+\t/* Client group */\n+\trc = epoll_wait(conn->fd_client_group, &event, 1, 0);\n+\tif ((rc == -1) || rc == 0)\n+\t\treturn rc;\n+\n+\tfd_client = event.data.fd;\n+\n+\t/* Data available */\n+\tif (event.events & EPOLLIN)\n+\t\trc_data = data_event_handle(conn, fd_client);\n+\n+\t/* Control events */\n+\tif (event.events & (EPOLLRDHUP | EPOLLERR | EPOLLHUP))\n+\t\trc_control = control_event_handle(conn, fd_client);\n+\n+\tif (rc_data || rc_control)\n+\t\treturn -1;\n+\n+\treturn 0;\n+}\ndiff --git a/app/graph/conn.h b/app/graph/conn.h\nnew file mode 100644\nindex 0000000000..770964cf4c\n--- /dev/null\n+++ b/app/graph/conn.h\n@@ -0,0 +1,46 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Marvell.\n+ */\n+\n+#ifndef APP_GRAPH_CONN_H\n+#define APP_GRAPH_CONN_H\n+\n+#define CONN_WELCOME_LEN_MAX 1024\n+#define CONN_PROMPT_LEN_MAX 16\n+\n+typedef void (*conn_msg_handle_t)(char *msg_in, char *msg_out, size_t msg_out_len_max, void *arg);\n+\n+struct conn {\n+\tchar *welcome;\n+\tchar *prompt;\n+\tchar *buf;\n+\tchar *msg_in;\n+\tchar *msg_out;\n+\tsize_t buf_size;\n+\tsize_t msg_in_len_max;\n+\tsize_t msg_out_len_max;\n+\tsize_t msg_in_len;\n+\tint fd_server;\n+\tint fd_client_group;\n+\tconn_msg_handle_t msg_handle;\n+\tvoid *msg_handle_arg;\n+};\n+\n+struct conn_params {\n+\tconst char *welcome;\n+\tconst char *prompt;\n+\tconst char *addr;\n+\tuint16_t port;\n+\tsize_t buf_size;\n+\tsize_t msg_in_len_max;\n+\tsize_t msg_out_len_max;\n+\tconn_msg_handle_t msg_handle;\n+\tvoid *msg_handle_arg;\n+};\n+\n+struct conn *conn_init(struct conn_params *p);\n+void conn_free(struct conn *conn);\n+int conn_req_poll(struct conn *conn);\n+int conn_msg_poll(struct conn *conn);\n+\n+#endif\ndiff --git a/app/graph/main.c b/app/graph/main.c\nindex 734a94444e..96548f49e7 100644\n--- a/app/graph/main.c\n+++ b/app/graph/main.c\n@@ -2,6 +2,7 @@\n  * Copyright(c) 2023 Marvell.\n  */\n \n+#include <errno.h>\n #include <fcntl.h>\n #include <getopt.h>\n #include <signal.h>\n@@ -11,19 +12,33 @@\n #include <sys/select.h>\n #include <unistd.h>\n \n+#include <rte_cycles.h>\n #include <rte_eal.h>\n #include <rte_launch.h>\n \n #include \"module_api.h\"\n \n volatile bool force_quit;\n+struct conn *conn;\n \n-static const char usage[] = \"%s EAL_ARGS -- -s SCRIPT \"\n+static const char usage[] = \"%s EAL_ARGS -- -s SCRIPT [-h HOST] [-p PORT] \"\n \t\t\t    \"[--help]\\n\";\n \n static struct app_params {\n+\tstruct conn_params conn;\n \tchar *script_name;\n } app = {\n+\t.conn = {\n+\t\t.welcome = \"\\nWelcome!\\n\\n\",\n+\t\t.prompt = \"graph> \",\n+\t\t.addr = \"0.0.0.0\",\n+\t\t.port = 8086,\n+\t\t.buf_size = 1024 * 1024,\n+\t\t.msg_in_len_max = 1024,\n+\t\t.msg_out_len_max = 1024 * 1024,\n+\t\t.msg_handle = cli_process,\n+\t\t.msg_handle_arg = NULL, /* set later. */\n+\t},\n \t.script_name = NULL,\n };\n \n@@ -42,7 +57,7 @@ app_args_parse(int argc, char **argv)\n \tstruct option lgopts[] = {\n \t\t{\"help\", 0, 0, 'H'},\n \t};\n-\tint s_present, n_args, i;\n+\tint h_present, p_present, s_present, n_args, i;\n \tchar *app_name = argv[0];\n \tint opt, option_index;\n \n@@ -59,10 +74,46 @@ app_args_parse(int argc, char **argv)\n \t\treturn 0;\n \n \t/* Parse args */\n+\th_present = 0;\n+\tp_present = 0;\n \ts_present = 0;\n \n-\twhile ((opt = getopt_long(argc, argv, \"s:\", lgopts, &option_index)) != EOF) {\n+\twhile ((opt = getopt_long(argc, argv, \"h:p:s:\", lgopts, &option_index)) != EOF) {\n \t\tswitch (opt) {\n+\t\tcase 'h':\n+\t\t\tif (h_present) {\n+\t\t\t\tprintf(\"Error: Multiple -h arguments\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\th_present = 1;\n+\n+\t\t\tif (!strlen(optarg)) {\n+\t\t\t\tprintf(\"Error: Argument for -h not provided\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\n+\t\t\tapp.conn.addr = strdup(optarg);\n+\t\t\tif (app.conn.addr == NULL) {\n+\t\t\t\tprintf(\"Error: Not enough memory\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tbreak;\n+\n+\t\tcase 'p':\n+\t\t\tif (p_present) {\n+\t\t\t\tprintf(\"Error: Multiple -p arguments\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\t\t\tp_present = 1;\n+\n+\t\t\tif (!strlen(optarg)) {\n+\t\t\t\tprintf(\"Error: Argument for -p not provided\\n\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\n+\t\t\tapp.conn.port = (uint16_t)strtoul(optarg, NULL, 10);\n+\t\t\tbreak;\n+\n \t\tcase 's':\n \t\t\tif (s_present) {\n \t\t\t\tprintf(\"Error: Multiple -s arguments\\n\");\n@@ -93,6 +144,26 @@ app_args_parse(int argc, char **argv)\n \treturn 0;\n }\n \n+bool\n+app_graph_exit(void)\n+{\n+\tstruct timeval tv;\n+\tfd_set fds;\n+\tint ret;\n+\tchar c;\n+\n+\tFD_ZERO(&fds);\n+\tFD_SET(0, &fds);\n+\ttv.tv_sec = 0;\n+\ttv.tv_usec = 100;\n+\tret = select(1, &fds, NULL, NULL, &tv);\n+\tif ((ret < 0 && errno == EINTR) || (ret == 1 && read(0, &c, 1) > 0))\n+\t\treturn true;\n+\telse\n+\t\treturn false;\n+\n+}\n+\n int\n main(int argc, char **argv)\n {\n@@ -118,10 +189,32 @@ main(int argc, char **argv)\n \n \t/* Script */\n \tif (app.script_name) {\n-\t\tcli_script_process(app.script_name, 0,\n-\t\t\t0, NULL);\n+\t\tcli_script_process(app.script_name, app.conn.msg_in_len_max,\n+\t\t\tapp.conn.msg_out_len_max, NULL);\n+\t}\n+\n+\t/* Connectivity */\n+\tapp.conn.msg_handle_arg = NULL;\n+\tconn = conn_init(&app.conn);\n+\tif (!conn) {\n+\t\tprintf(\"Error: Connectivity initialization failed\\n\");\n+\t\tgoto exit;\n+\t};\n+\n+\trte_delay_ms(1);\n+\tprintf(\"Press enter to exit\\n\");\n+\n+\t/* Dispatch loop */\n+\twhile (!force_quit) {\n+\t\tconn_req_poll(conn);\n+\n+\t\tconn_msg_poll(conn);\n+\t\tif (app_graph_exit())\n+\t\t\tforce_quit = true;\n \t}\n \n+exit:\n+\tconn_free(conn);\n \tcli_exit();\n \trte_eal_cleanup();\n \treturn 0;\ndiff --git a/app/graph/meson.build b/app/graph/meson.build\nindex ed33a04476..c8d2b41b69 100644\n--- a/app/graph/meson.build\n+++ b/app/graph/meson.build\n@@ -11,5 +11,6 @@ endif\n deps += ['graph', 'eal', 'lpm', 'ethdev', 'node', 'cmdline']\n sources = files(\n         'cli.c',\n+        'conn.c',\n         'main.c',\n )\ndiff --git a/app/graph/module_api.h b/app/graph/module_api.h\nindex 372aeae7e3..9826303f0c 100644\n--- a/app/graph/module_api.h\n+++ b/app/graph/module_api.h\n@@ -7,10 +7,13 @@\n \n #include <stdint.h>\n #include <stdbool.h>\n+\n #include \"cli.h\"\n+#include \"conn.h\"\n /*\n  * Externs\n  */\n extern volatile bool force_quit;\n \n+bool app_graph_exit(void);\n #endif\ndiff --git a/doc/guides/tools/graph.rst b/doc/guides/tools/graph.rst\nindex 5c15a6970b..cb3f523000 100644\n--- a/doc/guides/tools/graph.rst\n+++ b/doc/guides/tools/graph.rst\n@@ -39,6 +39,16 @@ Application Options\n \n Following are the application command-line options:\n \n+* ``-h``\n+\n+        Set the host IPv4 address over which telnet session can be opened.\n+        It is an optional parameter. Default host address is 0.0.0.0.\n+\n+* ``-p``\n+\n+        Set the L4 port number over which telnet session can be opened.\n+\tIt is an optional parameter. Default port is 8086.\n+\n * ``-s``\n \n         Script name with absolute path which specifies the use case. It is\n@@ -72,7 +82,35 @@ file to express the requested use case configuration.\n Runtime configuration\n ---------------------\n \n+Application allows some configuration to be modified at runtime using a telnet session.\n+Application initiates a telnet server with host address ``0.0.0.0`` and port number ``8086``\n+by default.\n+\n+if user passes ``-h`` and ``-p`` options while running application then corresponding\n+IP address and port number will be used for telnet session.\n+\n+After successful launch of application, client can connect to application using given\n+host & port and console will be accessed with prompt ``graph>``.\n+\n+Command to access a telnet session\n+\n+.. code-block:: console\n+\n+   telnet <host> <port>\n+\n+Example: ``dpdk-graph`` is started with -h 10.28.35.207 and -p 50000 then\n+\n+.. code-block:: console\n+\n+   $ telnet 10.28.35.207 50000\n+   Trying 10.28.35.207...\n+   Connected to 10.28.35.207.\n+   Escape character is '^]'.\n+\n+   Welcome!\n \n+   graph>\n+   graph>\n Created graph for use case\n --------------------------\n \n",
    "prefixes": [
        "v9",
        "02/12"
    ]
}