get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 91678,
    "url": "http://patches.dpdk.org/api/patches/91678/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1618595649-157464-3-git-send-email-bingz@nvidia.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": "<1618595649-157464-3-git-send-email-bingz@nvidia.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1618595649-157464-3-git-send-email-bingz@nvidia.com",
    "date": "2021-04-16T17:54:08",
    "name": "[v3,2/3] app/testpmd: add CLI for conntrack",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "036a4b708b54fca2f5e522a130befa5118b3aaee",
    "submitter": {
        "id": 1976,
        "url": "http://patches.dpdk.org/api/people/1976/?format=api",
        "name": "Bing Zhao",
        "email": "bingz@nvidia.com"
    },
    "delegate": {
        "id": 319,
        "url": "http://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1618595649-157464-3-git-send-email-bingz@nvidia.com/mbox/",
    "series": [
        {
            "id": 16453,
            "url": "http://patches.dpdk.org/api/series/16453/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=16453",
            "date": "2021-04-16T17:54:06",
            "name": "ethdev: introduce conntrack flow action and item",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/16453/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/91678/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/91678/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 2532BA0548;\n\tFri, 16 Apr 2021 19:54:32 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 2CCA01609F2;\n\tFri, 16 Apr 2021 19:54:22 +0200 (CEST)",
            "from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129])\n by mails.dpdk.org (Postfix) with ESMTP id 04E39161C32\n for <dev@dpdk.org>; Fri, 16 Apr 2021 19:54:19 +0200 (CEST)",
            "from Internal Mail-Server by MTLPINE1 (envelope-from\n bingz@nvidia.com) with SMTP; 16 Apr 2021 20:54:18 +0300",
            "from nvidia.com (mtbc-r640-01.mtbc.labs.mlnx [10.75.70.6])\n by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 13GHsAVP025093;\n Fri, 16 Apr 2021 20:54:16 +0300"
        ],
        "From": "Bing Zhao <bingz@nvidia.com>",
        "To": "orika@nvidia.com, thomas@monjalon.net, ferruh.yigit@intel.com,\n andrew.rybchenko@oktetlabs.ru",
        "Cc": "dev@dpdk.org, ajit.khaparde@broadcom.com, xiaoyun.li@intel.com",
        "Date": "Sat, 17 Apr 2021 01:54:08 +0800",
        "Message-Id": "<1618595649-157464-3-git-send-email-bingz@nvidia.com>",
        "X-Mailer": "git-send-email 2.5.5",
        "In-Reply-To": "<1618595649-157464-1-git-send-email-bingz@nvidia.com>",
        "References": "<1618062393-205611-1-git-send-email-bingz@nvidia.com>\n <1618595649-157464-1-git-send-email-bingz@nvidia.com>",
        "Subject": "[dpdk-dev] [PATCH v3 2/3] app/testpmd: add CLI for conntrack",
        "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",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "The command line for testing connection tracking is added. To create\na conntrack object, 3 parts are needed.\n  set conntrack com peer ...\n  set conntrack orig scale ...\n  set conntrack rply scale ...\nThis will create a full conntrack action structure for the indirect\naction. After the indirect action handle of \"conntrack\" created, it\ncould be used in the flow creation. Before updating, the same\nstructure is also needed together with the update command\n\"conntrack_update\" to update the \"dir\" or \"ctx\".\n\nAfter the flow with conntrack action created, the packet should jump\nto the next flow for the result checking with conntrack item. The\nstate is defined with bits and a valid combination could be\nsupported.\n\nSigned-off-by: Bing Zhao <bingz@nvidia.com>\n---\n app/test-pmd/cmdline.c      | 354 ++++++++++++++++++++++++++++++++++++\n app/test-pmd/cmdline_flow.c |  92 ++++++++++\n app/test-pmd/config.c       |  65 ++++++-\n app/test-pmd/testpmd.h      |   2 +\n 4 files changed, 512 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c\nindex 4d9e038ce8..a318544fc6 100644\n--- a/app/test-pmd/cmdline.c\n+++ b/app/test-pmd/cmdline.c\n@@ -13621,6 +13621,358 @@ cmdline_parse_inst_t cmd_set_mplsoudp_decap_with_vlan = {\n \t},\n };\n \n+/** Set connection tracking object common details */\n+struct cmd_set_conntrack_common_result {\n+\tcmdline_fixed_string_t set;\n+\tcmdline_fixed_string_t conntrack;\n+\tcmdline_fixed_string_t common;\n+\tcmdline_fixed_string_t peer;\n+\tcmdline_fixed_string_t is_orig;\n+\tcmdline_fixed_string_t enable;\n+\tcmdline_fixed_string_t live;\n+\tcmdline_fixed_string_t sack;\n+\tcmdline_fixed_string_t cack;\n+\tcmdline_fixed_string_t last_dir;\n+\tcmdline_fixed_string_t liberal;\n+\tcmdline_fixed_string_t state;\n+\tcmdline_fixed_string_t max_ack_win;\n+\tcmdline_fixed_string_t retrans;\n+\tcmdline_fixed_string_t last_win;\n+\tcmdline_fixed_string_t last_seq;\n+\tcmdline_fixed_string_t last_ack;\n+\tcmdline_fixed_string_t last_end;\n+\tcmdline_fixed_string_t last_index;\n+\tuint8_t stat;\n+\tuint8_t factor;\n+\tuint16_t peer_port;\n+\tuint32_t is_original;\n+\tuint32_t en;\n+\tuint32_t is_live;\n+\tuint32_t s_ack;\n+\tuint32_t c_ack;\n+\tuint32_t ld;\n+\tuint32_t lb;\n+\tuint8_t re_num;\n+\tuint8_t li;\n+\tuint16_t lw;\n+\tuint32_t ls;\n+\tuint32_t la;\n+\tuint32_t le;\n+};\n+\n+cmdline_parse_token_string_t cmd_set_conntrack_set =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t set, \"set\");\n+cmdline_parse_token_string_t cmd_set_conntrack_conntrack =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t conntrack, \"conntrack\");\n+cmdline_parse_token_string_t cmd_set_conntrack_conntrack =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t common, \"com\");\n+cmdline_parse_token_string_t cmd_set_conntrack_common_peer =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t peer, \"peer\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_peer_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      peer_port, RTE_UINT16);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_is_orig =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t is_orig, \"is_orig\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_is_orig_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      is_original, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_enable =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t enable, \"enable\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_enable_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      en, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_live =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t live, \"live\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_live_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      is_live, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_sack =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t sack, \"sack\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_sack_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      s_ack, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_cack =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t cack, \"cack\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_cack_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      c_ack, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_last_dir =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t last_dir, \"last_dir\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_last_dir_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      ld, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_liberal =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t liberal, \"liberal\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_liberal_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      lb, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_state =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t state, \"state\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_state_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      stat, RTE_UINT8);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_max_ackwin =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t max_ack_win, \"max_ack_win\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_max_ackwin_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      factor, RTE_UINT8);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_retrans =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t retrans, \"r_lim\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_retrans_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      re_num, RTE_UINT8);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_last_win =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t last_win, \"last_win\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_last_win_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      lw, RTE_UINT16);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_last_seq =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t last_seq, \"last_seq\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_last_seq_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      ls, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_last_ack =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t last_ack, \"last_ack\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_last_ack_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      la, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_last_end =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t last_end, \"last_end\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_last_end_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      le, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_common_last_index =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t\t last_index, \"last_index\");\n+cmdline_parse_token_num_t cmd_set_conntrack_common_last_index_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_common_result,\n+\t\t\t      li, RTE_UINT8);\n+\n+static void cmd_set_conntrack_common_parsed(void *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\t__rte_unused void *data)\n+{\n+\tstruct cmd_set_conntrack_common_result *res = parsed_result;\n+\n+\t/* No need to swap to big endian. */\n+\tconntrack_context.peer_port = res->peer_port;\n+\tconntrack_context.is_original_dir = res->is_original;\n+\tconntrack_context.enable = res->en;\n+\tconntrack_context.live_connection = res->is_live;\n+\tconntrack_context.selective_ack = res->s_ack;\n+\tconntrack_context.challenge_ack_passed = res->c_ack;\n+\tconntrack_context.last_direction = res->ld;\n+\tconntrack_context.liberal_mode = res->lb;\n+\tconntrack_context.state = (enum rte_flow_conntrack_state)res->stat;\n+\tconntrack_context.max_ack_window = res->factor;\n+\tconntrack_context.retransmission_limit = res->re_num;\n+\tconntrack_context.last_window = res->lw;\n+\tconntrack_context.last_index =\n+\t\t(enum rte_flow_conntrack_tcp_last_index)res->li;\n+\tconntrack_context.last_seq = res->ls;\n+\tconntrack_context.last_ack = res->la;\n+\tconntrack_context.last_end = res->le;\n+}\n+\n+cmdline_parse_inst_t cmd_set_conntrack_common = {\n+\t.f = cmd_set_conntrack_common_parsed,\n+\t.data = NULL,\n+\t.help_str = \"set conntrack com peer <port_id> is_orig <dir> enable <en>\"\n+\t\t\" live <ack_seen> sack <en> cack <passed> last_dir <dir>\"\n+\t\t\" liberal <en> state <s> max_ack_win <factor> r_lim <num>\"\n+\t\t\" last_win <win> last_seq <seq> last_ack <ack> last_end <end>\"\n+\t\t\" last_index <flag>\",\n+\t.tokens = {\n+\t\t(void *)&cmd_set_conntrack_set,\n+\t\t(void *)&cmd_set_conntrack_conntrack,\n+\t\t(void *)&cmd_set_conntrack_common_peer,\n+\t\t(void *)&cmd_set_conntrack_common_peer_value,\n+\t\t(void *)&cmd_set_conntrack_common_is_orig,\n+\t\t(void *)&cmd_set_conntrack_common_is_orig_value,\n+\t\t(void *)&cmd_set_conntrack_common_enable,\n+\t\t(void *)&cmd_set_conntrack_common_enable_value,\n+\t\t(void *)&cmd_set_conntrack_common_live,\n+\t\t(void *)&cmd_set_conntrack_common_live_value,\n+\t\t(void *)&cmd_set_conntrack_common_sack,\n+\t\t(void *)&cmd_set_conntrack_common_sack_value,\n+\t\t(void *)&cmd_set_conntrack_common_cack,\n+\t\t(void *)&cmd_set_conntrack_common_cack_value,\n+\t\t(void *)&cmd_set_conntrack_common_last_dir,\n+\t\t(void *)&cmd_set_conntrack_common_last_dir_value,\n+\t\t(void *)&cmd_set_conntrack_common_liberal,\n+\t\t(void *)&cmd_set_conntrack_common_liberal_value,\n+\t\t(void *)&cmd_set_conntrack_common_state,\n+\t\t(void *)&cmd_set_conntrack_common_state_value,\n+\t\t(void *)&cmd_set_conntrack_common_max_ackwin,\n+\t\t(void *)&cmd_set_conntrack_common_max_ackwin_value,\n+\t\t(void *)&cmd_set_conntrack_common_retrans,\n+\t\t(void *)&cmd_set_conntrack_common_retrans_value,\n+\t\t(void *)&cmd_set_conntrack_common_last_win,\n+\t\t(void *)&cmd_set_conntrack_common_last_win_value,\n+\t\t(void *)&cmd_set_conntrack_common_last_seq,\n+\t\t(void *)&cmd_set_conntrack_common_last_seq_value,\n+\t\t(void *)&cmd_set_conntrack_common_last_ack,\n+\t\t(void *)&cmd_set_conntrack_common_last_ack_value,\n+\t\t(void *)&cmd_set_conntrack_common_last_end,\n+\t\t(void *)&cmd_set_conntrack_common_last_end_value,\n+\t\t(void *)&cmd_set_conntrack_common_last_index,\n+\t\t(void *)&cmd_set_conntrack_common_last_index_value,\n+\t\tNULL,\n+\t},\n+};\n+\n+/** Set connection tracking object both directions' details */\n+struct cmd_set_conntrack_dir_result {\n+\tcmdline_fixed_string_t set;\n+\tcmdline_fixed_string_t conntrack;\n+\tcmdline_fixed_string_t dir;\n+\tcmdline_fixed_string_t scale;\n+\tcmdline_fixed_string_t fin;\n+\tcmdline_fixed_string_t ack_seen;\n+\tcmdline_fixed_string_t unack;\n+\tcmdline_fixed_string_t sent_end;\n+\tcmdline_fixed_string_t reply_end;\n+\tcmdline_fixed_string_t max_win;\n+\tcmdline_fixed_string_t max_ack;\n+\tuint32_t factor;\n+\tuint32_t f;\n+\tuint32_t as;\n+\tuint32_t un;\n+\tuint32_t se;\n+\tuint32_t re;\n+\tuint32_t mw;\n+\tuint32_t ma;\n+};\n+\n+cmdline_parse_token_string_t cmd_set_conntrack_dir_set =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t\t set, \"set\");\n+cmdline_parse_token_string_t cmd_set_conntrack_dir_conntrack =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t\t conntrack, \"conntrack\");\n+cmdline_parse_token_string_t cmd_set_conntrack_dir_dir =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t\t dir, \"orig#rply\");\n+cmdline_parse_token_string_t cmd_set_conntrack_dir_scale =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t\t scale, \"scale\");\n+cmdline_parse_token_num_t cmd_set_conntrack_dir_scale_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t      factor, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_dir_fin =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t\t fin, \"fin\");\n+cmdline_parse_token_num_t cmd_set_conntrack_dir_fin_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t      f, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_dir_ack =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t\t ack_seen, \"acked\");\n+cmdline_parse_token_num_t cmd_set_conntrack_dir_ack_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t      as, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_dir_unack_data =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t\t unack, \"unack_data\");\n+cmdline_parse_token_num_t cmd_set_conntrack_dir_unack_data_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t      un, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_dir_sent_end =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t\t sent_end, \"sent_end\");\n+cmdline_parse_token_num_t cmd_set_conntrack_dir_sent_end_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t      se, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_dir_reply_end =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t\t reply_end, \"reply_end\");\n+cmdline_parse_token_num_t cmd_set_conntrack_dir_reply_end_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t      re, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_dir_max_win =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t\t max_win, \"max_win\");\n+cmdline_parse_token_num_t cmd_set_conntrack_dir_max_win_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t      mw, RTE_UINT32);\n+cmdline_parse_token_string_t cmd_set_conntrack_dir_max_ack =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t\t max_ack, \"max_ack\");\n+cmdline_parse_token_num_t cmd_set_conntrack_dir_max_ack_value =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_set_conntrack_dir_result,\n+\t\t\t      ma, RTE_UINT32);\n+\n+static void cmd_set_conntrack_dir_parsed(void *parsed_result,\n+\t__rte_unused struct cmdline *cl,\n+\t__rte_unused void *data)\n+{\n+\tstruct cmd_set_conntrack_dir_result *res = parsed_result;\n+\tstruct rte_flow_tcp_dir_param *dir = NULL;\n+\n+\tif (strcmp(res->dir, \"orig\") == 0)\n+\t\tdir = &conntrack_context.original_dir;\n+\telse if (strcmp(res->dir, \"rply\") == 0)\n+\t\tdir = &conntrack_context.reply_dir;\n+\telse\n+\t\treturn;\n+\tdir->scale = res->factor;\n+\tdir->close_initiated = res->f;\n+\tdir->last_ack_seen = res->as;\n+\tdir->data_unacked = res->un;\n+\tdir->sent_end = res->se;\n+\tdir->reply_end = res->re;\n+\tdir->max_ack = res->ma;\n+\tdir->max_win = res->mw;\n+}\n+\n+cmdline_parse_inst_t cmd_set_conntrack_dir = {\n+\t.f = cmd_set_conntrack_dir_parsed,\n+\t.data = NULL,\n+\t.help_str = \"set conntrack orig|rply scale <factor> fin <sent>\"\n+\t\t    \" acked <seen> unack_data <unack> sent_end <sent>\"\n+\t\t    \" reply_end <reply> max_win <win> max_ack <ack>\",\n+\t.tokens = {\n+\t\t(void *)&cmd_set_conntrack_set,\n+\t\t(void *)&cmd_set_conntrack_conntrack,\n+\t\t(void *)&cmd_set_conntrack_dir_dir,\n+\t\t(void *)&cmd_set_conntrack_dir_scale,\n+\t\t(void *)&cmd_set_conntrack_dir_scale_value,\n+\t\t(void *)&cmd_set_conntrack_dir_fin,\n+\t\t(void *)&cmd_set_conntrack_dir_fin_value,\n+\t\t(void *)&cmd_set_conntrack_dir_ack,\n+\t\t(void *)&cmd_set_conntrack_dir_ack_value,\n+\t\t(void *)&cmd_set_conntrack_dir_unack_data,\n+\t\t(void *)&cmd_set_conntrack_dir_unack_data_value,\n+\t\t(void *)&cmd_set_conntrack_dir_sent_end,\n+\t\t(void *)&cmd_set_conntrack_dir_sent_end_value,\n+\t\t(void *)&cmd_set_conntrack_dir_reply_end,\n+\t\t(void *)&cmd_set_conntrack_dir_reply_end_value,\n+\t\t(void *)&cmd_set_conntrack_dir_max_win,\n+\t\t(void *)&cmd_set_conntrack_dir_max_win_value,\n+\t\t(void *)&cmd_set_conntrack_dir_max_ack,\n+\t\t(void *)&cmd_set_conntrack_dir_max_ack_value,\n+\t\tNULL,\n+\t},\n+};\n+\n /* Strict link priority scheduling mode setting */\n static void\n cmd_strict_link_prio_parsed(\n@@ -17120,6 +17472,8 @@ cmdline_parse_ctx_t main_ctx[] = {\n \t(cmdline_parse_inst_t *)&cmd_set_mplsoudp_encap_with_vlan,\n \t(cmdline_parse_inst_t *)&cmd_set_mplsoudp_decap,\n \t(cmdline_parse_inst_t *)&cmd_set_mplsoudp_decap_with_vlan,\n+\t(cmdline_parse_inst_t *)&cmd_set_conntrack_common,\n+\t(cmdline_parse_inst_t *)&cmd_set_conntrack_dir,\n \t(cmdline_parse_inst_t *)&cmd_ddp_add,\n \t(cmdline_parse_inst_t *)&cmd_ddp_del,\n \t(cmdline_parse_inst_t *)&cmd_ddp_get_list,\ndiff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c\nindex c5381c638b..d82b08c609 100644\n--- a/app/test-pmd/cmdline_flow.c\n+++ b/app/test-pmd/cmdline_flow.c\n@@ -293,6 +293,7 @@ enum index {\n \tITEM_GENEVE_OPT_TYPE,\n \tITEM_GENEVE_OPT_LENGTH,\n \tITEM_GENEVE_OPT_DATA,\n+\tITEM_CONNTRACK,\n \n \t/* Validate/create actions. */\n \tACTIONS,\n@@ -431,6 +432,10 @@ enum index {\n \tACTION_MODIFY_FIELD_SRC_OFFSET,\n \tACTION_MODIFY_FIELD_SRC_VALUE,\n \tACTION_MODIFY_FIELD_WIDTH,\n+\tACTION_CONNTRACK,\n+\tACTION_CONNTRACK_UPDATE,\n+\tACTION_CONNTRACK_UPDATE_DIR,\n+\tACTION_CONNTRACK_UPDATE_CTX,\n };\n \n /** Maximum size for pattern in struct rte_flow_item_raw. */\n@@ -569,6 +574,8 @@ struct mplsoudp_encap_conf mplsoudp_encap_conf;\n \n struct mplsoudp_decap_conf mplsoudp_decap_conf;\n \n+struct rte_flow_action_conntrack conntrack_context;\n+\n #define ACTION_SAMPLE_ACTIONS_NUM 10\n #define RAW_SAMPLE_CONFS_MAX_NUM 8\n /** Storage for struct rte_flow_action_sample including external data. */\n@@ -968,6 +975,7 @@ static const enum index next_item[] = {\n \tITEM_PFCP,\n \tITEM_ECPRI,\n \tITEM_GENEVE_OPT,\n+\tITEM_CONNTRACK,\n \tEND_SET,\n \tZERO,\n };\n@@ -1382,6 +1390,8 @@ static const enum index next_action[] = {\n \tACTION_SAMPLE,\n \tACTION_INDIRECT,\n \tACTION_MODIFY_FIELD,\n+\tACTION_CONNTRACK,\n+\tACTION_CONNTRACK_UPDATE,\n \tZERO,\n };\n \n@@ -1650,6 +1660,13 @@ static const enum index action_modify_field_src[] = {\n \tZERO,\n };\n \n+static const enum index action_update_conntrack[] = {\n+\tACTION_CONNTRACK_UPDATE_DIR,\n+\tACTION_CONNTRACK_UPDATE_CTX,\n+\tACTION_NEXT,\n+\tZERO,\n+};\n+\n static int parse_set_raw_encap_decap(struct context *, const struct token *,\n \t\t\t\t     const char *, unsigned int,\n \t\t\t\t     void *, unsigned int);\n@@ -1740,6 +1757,10 @@ static int\n parse_vc_modify_field_id(struct context *ctx, const struct token *token,\n \t\t\t\tconst char *str, unsigned int len, void *buf,\n \t\t\t\tunsigned int size);\n+static int\n+parse_vc_action_conntrack_update(struct context *ctx, const struct token *token,\n+\t\t\t const char *str, unsigned int len, void *buf,\n+\t\t\t unsigned int size);\n static int parse_destroy(struct context *, const struct token *,\n \t\t\t const char *, unsigned int,\n \t\t\t void *, unsigned int);\n@@ -3400,6 +3421,13 @@ static const struct token token_list[] = {\n \t\t\t\t(sizeof(struct rte_flow_item_geneve_opt),\n \t\t\t\tITEM_GENEVE_OPT_DATA_SIZE)),\n \t},\n+\t[ITEM_CONNTRACK] = {\n+\t\t.name = \"conntrack\",\n+\t\t.help = \"conntrack state\",\n+\t\t.next = NEXT(NEXT_ENTRY(ITEM_NEXT), NEXT_ENTRY(UNSIGNED),\n+\t\t\t     item_param),\n+\t\t.args = ARGS(ARGS_ENTRY(struct rte_flow_item_conntrack, flags)),\n+\t},\n \t/* Validate/create actions. */\n \t[ACTIONS] = {\n \t\t.name = \"actions\",\n@@ -4498,6 +4526,34 @@ static const struct token token_list[] = {\n \t\t.call = parse_vc_action_sample_index,\n \t\t.comp = comp_set_sample_index,\n \t},\n+\t[ACTION_CONNTRACK] = {\n+\t\t.name = \"conntrack\",\n+\t\t.help = \"create a conntrack object\",\n+\t\t.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),\n+\t\t.priv = PRIV_ACTION(CONNTRACK,\n+\t\t\t\t    sizeof(struct rte_flow_action_conntrack)),\n+\t\t.call = parse_vc,\n+\t},\n+\t[ACTION_CONNTRACK_UPDATE] = {\n+\t\t.name = \"conntrack_update\",\n+\t\t.help = \"update a conntrack object\",\n+\t\t.next = NEXT(action_update_conntrack),\n+\t\t.priv = PRIV_ACTION(CONNTRACK,\n+\t\t\t\t    sizeof(struct rte_flow_modify_conntrack)),\n+\t\t.call = parse_vc,\n+\t},\n+\t[ACTION_CONNTRACK_UPDATE_DIR] = {\n+\t\t.name = \"dir\",\n+\t\t.help = \"update a conntrack object direction\",\n+\t\t.next = NEXT(action_update_conntrack),\n+\t\t.call = parse_vc_action_conntrack_update,\n+\t},\n+\t[ACTION_CONNTRACK_UPDATE_CTX] = {\n+\t\t.name = \"ctx\",\n+\t\t.help = \"update a conntrack object context\",\n+\t\t.next = NEXT(action_update_conntrack),\n+\t\t.call = parse_vc_action_conntrack_update,\n+\t},\n \t/* Indirect action destroy arguments. */\n \t[INDIRECT_ACTION_DESTROY_ID] = {\n \t\t.name = \"action_id\",\n@@ -6304,6 +6360,42 @@ parse_vc_modify_field_id(struct context *ctx, const struct token *token,\n \treturn len;\n }\n \n+/** Parse the conntrack update, not a rte_flow_action. */\n+static int\n+parse_vc_action_conntrack_update(struct context *ctx, const struct token *token,\n+\t\t\t const char *str, unsigned int len, void *buf,\n+\t\t\t unsigned int size)\n+{\n+\tstruct buffer *out = buf;\n+\tstruct rte_flow_modify_conntrack *ct_modify = NULL;\n+\n+\t(void)size;\n+\tif (ctx->curr != ACTION_CONNTRACK_UPDATE_CTX &&\n+\t    ctx->curr != ACTION_CONNTRACK_UPDATE_DIR)\n+\t    return -1;\n+\t/* Token name must match. */\n+\tif (parse_default(ctx, token, str, len, NULL, 0) < 0)\n+\t\treturn -1;\n+\tct_modify = (struct rte_flow_modify_conntrack *)out->args.vc.data;\n+\t/* Nothing else to do if there is no buffer. */\n+\tif (!out)\n+\t\treturn len;\n+\tif (ctx->curr == ACTION_CONNTRACK_UPDATE_DIR) {\n+\t\tct_modify->new_ct.is_original_dir =\n+\t\t\t\tconntrack_context.is_original_dir;\n+\t\tct_modify->direction = 1;\n+\t} else {\n+\t\tuint32_t old_dir;\n+\n+\t\told_dir = ct_modify->new_ct.is_original_dir;\n+\t\tmemcpy(&ct_modify->new_ct, &conntrack_context,\n+\t\t       sizeof(conntrack_context));\n+\t\tct_modify->new_ct.is_original_dir = old_dir;\n+\t\tct_modify->state = 1;\n+\t}\n+\treturn len;\n+}\n+\n /** Parse tokens for destroy command. */\n static int\n parse_destroy(struct context *ctx, const struct token *token,\ndiff --git a/app/test-pmd/config.c b/app/test-pmd/config.c\nindex c219ef25f7..02b7d4719a 100644\n--- a/app/test-pmd/config.c\n+++ b/app/test-pmd/config.c\n@@ -1484,6 +1484,11 @@ port_action_handle_create(portid_t port_id, uint32_t id,\n \n \t\tpia->age_type = ACTION_AGE_CONTEXT_TYPE_INDIRECT_ACTION;\n \t\tage->context = &pia->age_type;\n+\t} else if (action->type == RTE_FLOW_ACTION_TYPE_CONNTRACK) {\n+\t\tstruct rte_flow_action_conntrack *ct =\n+\t\t(struct rte_flow_action_conntrack *)(uintptr_t)(action->conf);\n+\n+\t\tmemcpy(ct, &conntrack_context, sizeof(*ct));\n \t}\n \t/* Poisoning to make sure PMDs update it in case of error. */\n \tmemset(&error, 0x22, sizeof(error));\n@@ -1565,11 +1570,24 @@ port_action_handle_update(portid_t port_id, uint32_t id,\n {\n \tstruct rte_flow_error error;\n \tstruct rte_flow_action_handle *action_handle;\n+\tstruct port_indirect_action *pia;\n+\tconst void *update;\n \n \taction_handle = port_action_handle_get_by_id(port_id, id);\n \tif (!action_handle)\n \t\treturn -EINVAL;\n-\tif (rte_flow_action_handle_update(port_id, action_handle, action,\n+\tpia = action_get_by_id(port_id, id);\n+\tif (!pia)\n+\t\treturn -EINVAL;\n+\tswitch (pia->type) {\n+\tcase RTE_FLOW_ACTION_TYPE_CONNTRACK:\n+\t\tupdate = action->conf;\n+\t\tbreak;\n+\tdefault:\n+\t\tupdate = action;\n+\t\tbreak;\n+\t}\n+\tif (rte_flow_action_handle_update(port_id, action_handle, update,\n \t\t\t\t\t  &error)) {\n \t\treturn port_flow_complain(&error);\n \t}\n@@ -1622,6 +1640,51 @@ port_action_handle_query(portid_t port_id, uint32_t id)\n \t\t}\n \t\tdata = NULL;\n \t\tbreak;\n+\tcase RTE_FLOW_ACTION_TYPE_CONNTRACK:\n+\t\tif (!ret) {\n+\t\t\tstruct rte_flow_action_conntrack *ct = data;\n+\n+\t\t\tprintf(\"Conntrack Context:\\n\"\n+\t\t\t       \"  Peer: %u, Flow dir: %s, Enable: %u\\n\"\n+\t\t\t       \"  Live: %u, SACK: %u, CACK: %u\\n\"\n+\t\t\t       \"  Packet dir: %s, Liberal: %u, State: %u\\n\"\n+\t\t\t       \"  Factor: %u, Retrans: %u, TCP flags: %u\\n\"\n+\t\t\t       \"  Last Seq: %u, Last ACK: %u\\n\"\n+\t\t\t       \"  Last Win: %u, Last End: %u\\n\",\n+\t\t\t       ct->peer_port,\n+\t\t\t       ct->is_original_dir ? \"Original\" : \"Reply\",\n+\t\t\t       ct->enable, ct->live_connection,\n+\t\t\t       ct->selective_ack, ct->challenge_ack_passed,\n+\t\t\t       ct->last_direction ? \"Original\" : \"Reply\",\n+\t\t\t       ct->liberal_mode, ct->state,\n+\t\t\t       ct->max_ack_window, ct->retransmission_limit,\n+\t\t\t       ct->last_index, ct->last_seq, ct->last_ack,\n+\t\t\t       ct->last_window, ct->last_end);\n+\t\t\tprintf(\"  Original Dir:\\n\"\n+\t\t\t       \"    scale: %u, fin: %u, ack seen: %u\\n\"\n+\t\t\t       \" unacked data: %u\\n    Sent end: %u,\"\n+\t\t\t       \"    Reply end: %u, Max win: %u, Max ACK: %u\\n\",\n+\t\t\t       ct->original_dir.scale,\n+\t\t\t       ct->original_dir.close_initiated,\n+\t\t\t       ct->original_dir.last_ack_seen,\n+\t\t\t       ct->original_dir.data_unacked,\n+\t\t\t       ct->original_dir.sent_end,\n+\t\t\t       ct->original_dir.reply_end,\n+\t\t\t       ct->original_dir.max_win,\n+\t\t\t       ct->original_dir.max_ack);\n+\t\t\tprintf(\"  Reply Dir:\\n\"\n+\t\t\t       \"    scale: %u, fin: %u, ack seen: %u\\n\"\n+\t\t\t       \" unacked data: %u\\n    Sent end: %u,\"\n+\t\t\t       \"    Reply end: %u, Max win: %u, Max ACK: %u\\n\",\n+\t\t\t       ct->reply_dir.scale,\n+\t\t\t       ct->reply_dir.close_initiated,\n+\t\t\t       ct->reply_dir.last_ack_seen,\n+\t\t\t       ct->reply_dir.data_unacked,\n+\t\t\t       ct->reply_dir.sent_end, ct->reply_dir.reply_end,\n+\t\t\t       ct->reply_dir.max_win, ct->reply_dir.max_ack);\n+\t\t}\n+\t\tdata = NULL;\n+\t\tbreak;\n \tdefault:\n \t\tprintf(\"Indirect action %u (type: %d) on port %u doesn't\"\n \t\t       \" support query\\n\", id, pia->type, port_id);\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex c314b30f2e..9530ec5fe0 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -630,6 +630,8 @@ extern struct mplsoudp_decap_conf mplsoudp_decap_conf;\n \n extern enum rte_eth_rx_mq_mode rx_mq_mode;\n \n+extern struct rte_flow_action_conntrack conntrack_context;\n+\n static inline unsigned int\n lcore_num(void)\n {\n",
    "prefixes": [
        "v3",
        "2/3"
    ]
}