get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 1278,
    "url": "https://patches.dpdk.org/api/patches/1278/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/1415984609-2484-9-git-send-email-olivier.matz@6wind.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<1415984609-2484-9-git-send-email-olivier.matz@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1415984609-2484-9-git-send-email-olivier.matz@6wind.com",
    "date": "2014-11-14T17:03:24",
    "name": "[dpdk-dev,v2,08/13] testpmd: rework csum forward engine",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "fa54ef2f9aba82056e460916dc21a107d71d9d82",
    "submitter": {
        "id": 8,
        "url": "https://patches.dpdk.org/api/people/8/?format=api",
        "name": "Olivier Matz",
        "email": "olivier.matz@6wind.com"
    },
    "delegate": null,
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/1415984609-2484-9-git-send-email-olivier.matz@6wind.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/1278/comments/",
    "check": "pending",
    "checks": "https://patches.dpdk.org/api/patches/1278/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id F0CDD7FDB;\n\tFri, 14 Nov 2014 17:54:08 +0100 (CET)",
            "from mail-wi0-f180.google.com (mail-wi0-f180.google.com\n\t[209.85.212.180]) by dpdk.org (Postfix) with ESMTP id 6373B7F89\n\tfor <dev@dpdk.org>; Fri, 14 Nov 2014 17:53:55 +0100 (CET)",
            "by mail-wi0-f180.google.com with SMTP id hi2so3354934wib.1\n\tfor <dev@dpdk.org>; Fri, 14 Nov 2014 09:03:59 -0800 (PST)",
            "from glumotte.dev.6wind.com (guy78-3-82-239-227-177.fbx.proxad.net.\n\t[82.239.227.177]) by mx.google.com with ESMTPSA id\n\tcu9sm40352554wjb.0.2014.11.14.09.03.57 for <multiple recipients>\n\t(version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tFri, 14 Nov 2014 09:03:58 -0800 (PST)"
        ],
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20130820;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=sO3rUnioYxu26NpUiYm6D5JI9/XBkfbKhj6CjkwZ1Es=;\n\tb=Jieuer1fsX7M2aM1PyuQPQMJiOVA85Qd2JtiomW+VD/PrLeh4y/mTRiLr5/MnVUluh\n\t7XH6fK3bsDF2dXZBvAED2uY/rTEUHM9uuikEw4sc0wXISWL15vtl1kG095HYIg25vEAF\n\tfBX+s5IrpIQ/JEICwLAQDJfcQF5Qeyq22you8ToM1jZ6BhbKdho2+gtpyPOu/QhX7HbV\n\tvE/rNcZCDoYuv4cXuFMdgXFlnzYGhgDa7TbuSSiYRfw13ZDzvieZLpk/UdPPw02agYcE\n\tGU+dHCGW0atRWtiXeq85WLMytpDySmRx+1WPI8tzrgJr8xDoMI13iaF/nRJfSJnUBO8G\n\tUMJg==",
        "X-Gm-Message-State": "ALoCoQmp+JM5gI33PfcD3HlsiL+UmG6kwgLTgSr1dTWxE9k+kBzXD2/lT8sdG+9FPiJcCZXR/yYu",
        "X-Received": "by 10.194.178.231 with SMTP id\n\tdb7mr15367596wjc.112.1415984639151; \n\tFri, 14 Nov 2014 09:03:59 -0800 (PST)",
        "From": "Olivier Matz <olivier.matz@6wind.com>",
        "To": "dev@dpdk.org",
        "Date": "Fri, 14 Nov 2014 18:03:24 +0100",
        "Message-Id": "<1415984609-2484-9-git-send-email-olivier.matz@6wind.com>",
        "X-Mailer": "git-send-email 2.1.0",
        "In-Reply-To": "<1415984609-2484-1-git-send-email-olivier.matz@6wind.com>",
        "References": "<1415635166-1364-1-git-send-email-olivier.matz@6wind.com>\n\t<1415984609-2484-1-git-send-email-olivier.matz@6wind.com>",
        "Cc": "jigsaw@gmail.com",
        "Subject": "[dpdk-dev] [PATCH v2 08/13] testpmd: rework csum forward engine",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "The csum forward engine was becoming too complex to be used and\nextended (the next commits want to add the support of TSO):\n\n- no explaination about what the code does\n- code is not factorized, lots of code duplicated, especially between\n  ipv4/ipv6\n- user command line api: use of bitmasks that need to be calculated by\n  the user\n- the user flags don't have the same semantic:\n  - for legacy IP/UDP/TCP/SCTP, it selects software or hardware checksum\n  - for other (vxlan), it selects between hardware checksum or no\n    checksum\n- the code relies too much on flags set by the driver without software\n  alternative (ex: PKT_RX_TUNNEL_IPV4_HDR). It is nice to be able to\n  compare a software implementation with the hardware offload.\n\nThis commit tries to fix these issues, and provide a simple definition\nof what is done by the forward engine:\n\n * Receive a burst of packets, and for supported packet types:\n *  - modify the IPs\n *  - reprocess the checksum in SW or HW, depending on testpmd command line\n *    configuration\n * Then packets are transmitted on the output port.\n *\n * Supported packets are:\n *   Ether / (vlan) / IP|IP6 / UDP|TCP|SCTP .\n *   Ether / (vlan) / IP|IP6 / UDP / VxLAN / Ether / IP|IP6 / UDP|TCP|SCTP\n *\n * The network parser supposes that the packet is contiguous, which may\n * not be the case in real life.\n\nSigned-off-by: Olivier Matz <olivier.matz@6wind.com>\n---\n app/test-pmd/cmdline.c  | 151 ++++++++---\n app/test-pmd/config.c   |  11 -\n app/test-pmd/csumonly.c | 668 ++++++++++++++++++++++--------------------------\n app/test-pmd/testpmd.h  |  17 +-\n 4 files changed, 423 insertions(+), 424 deletions(-)",
    "diff": "diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c\nindex 4c3fc76..0361e58 100644\n--- a/app/test-pmd/cmdline.c\n+++ b/app/test-pmd/cmdline.c\n@@ -310,19 +310,14 @@ static void cmd_help_long_parsed(void *parsed_result,\n \t\t\t\"    Disable hardware insertion of a VLAN header in\"\n \t\t\t\" packets sent on a port.\\n\\n\"\n \n-\t\t\t\"tx_checksum set (mask) (port_id)\\n\"\n-\t\t\t\"    Enable hardware insertion of checksum offload with\"\n-\t\t\t\" the 8-bit mask, 0~0xff, in packets sent on a port.\\n\"\n-\t\t\t\"        bit 0 - insert ip   checksum offload if set\\n\"\n-\t\t\t\"        bit 1 - insert udp  checksum offload if set\\n\"\n-\t\t\t\"        bit 2 - insert tcp  checksum offload if set\\n\"\n-\t\t\t\"        bit 3 - insert sctp checksum offload if set\\n\"\n-\t\t\t\"        bit 4 - insert inner ip  checksum offload if set\\n\"\n-\t\t\t\"        bit 5 - insert inner udp checksum offload if set\\n\"\n-\t\t\t\"        bit 6 - insert inner tcp checksum offload if set\\n\"\n-\t\t\t\"        bit 7 - insert inner sctp checksum offload if set\\n\"\n+\t\t\t\"tx_cksum set (ip|udp|tcp|sctp|vxlan) (hw|sw) (port_id)\\n\"\n+\t\t\t\"    Enable hardware calculation of checksum with when\"\n+\t\t\t\" transmitting a packet using 'csum' forward engine.\\n\"\n \t\t\t\"    Please check the NIC datasheet for HW limits.\\n\\n\"\n \n+\t\t\t\"tx_checksum show (port_id)\\n\"\n+\t\t\t\"    Display tx checksum offload configuration\\n\\n\"\n+\n \t\t\t\"set fwd (%s)\\n\"\n \t\t\t\"    Set packet forwarding mode.\\n\\n\"\n \n@@ -2738,48 +2733,131 @@ cmdline_parse_inst_t cmd_tx_vlan_reset = {\n \n \n /* *** ENABLE HARDWARE INSERTION OF CHECKSUM IN TX PACKETS *** */\n-struct cmd_tx_cksum_set_result {\n+struct cmd_tx_cksum_result {\n \tcmdline_fixed_string_t tx_cksum;\n-\tcmdline_fixed_string_t set;\n-\tuint8_t cksum_mask;\n+\tcmdline_fixed_string_t mode;\n+\tcmdline_fixed_string_t proto;\n+\tcmdline_fixed_string_t hwsw;\n \tuint8_t port_id;\n };\n \n static void\n-cmd_tx_cksum_set_parsed(void *parsed_result,\n+cmd_tx_cksum_parsed(void *parsed_result,\n \t\t       __attribute__((unused)) struct cmdline *cl,\n \t\t       __attribute__((unused)) void *data)\n {\n-\tstruct cmd_tx_cksum_set_result *res = parsed_result;\n+\tstruct cmd_tx_cksum_result *res = parsed_result;\n+\tint hw = 0;\n+\tuint16_t ol_flags, mask = 0;\n+\tstruct rte_eth_dev_info dev_info;\n+\n+\tif (port_id_is_invalid(res->port_id)) {\n+\t\tprintf(\"invalid port %d\\n\", res->port_id);\n+\t\treturn;\n+\t}\n \n-\ttx_cksum_set(res->port_id, res->cksum_mask);\n+\tif (!strcmp(res->mode, \"set\")) {\n+\n+\t\tif (!strcmp(res->hwsw, \"hw\"))\n+\t\t\thw = 1;\n+\n+\t\tif (!strcmp(res->proto, \"ip\")) {\n+\t\t\tmask = TESTPMD_TX_OFFLOAD_IP_CKSUM;\n+\t\t} else if (!strcmp(res->proto, \"udp\")) {\n+\t\t\tmask = TESTPMD_TX_OFFLOAD_UDP_CKSUM;\n+\t\t} else if (!strcmp(res->proto, \"tcp\")) {\n+\t\t\tmask = TESTPMD_TX_OFFLOAD_TCP_CKSUM;\n+\t\t} else if (!strcmp(res->proto, \"sctp\")) {\n+\t\t\tmask = TESTPMD_TX_OFFLOAD_SCTP_CKSUM;\n+\t\t} else if (!strcmp(res->proto, \"vxlan\")) {\n+\t\t\tmask = TESTPMD_TX_OFFLOAD_VXLAN_CKSUM;\n+\t\t}\n+\n+\t\tif (hw)\n+\t\t\tports[res->port_id].tx_ol_flags |= mask;\n+\t\telse\n+\t\t\tports[res->port_id].tx_ol_flags &= (~mask);\n+\t}\n+\n+\tol_flags = ports[res->port_id].tx_ol_flags;\n+\tprintf(\"IP checksum offload is %s\\n\",\n+\t\t(ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) ? \"hw\" : \"sw\");\n+\tprintf(\"UDP checksum offload is %s\\n\",\n+\t\t(ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) ? \"hw\" : \"sw\");\n+\tprintf(\"TCP checksum offload is %s\\n\",\n+\t\t(ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) ? \"hw\" : \"sw\");\n+\tprintf(\"SCTP checksum offload is %s\\n\",\n+\t\t(ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) ? \"hw\" : \"sw\");\n+\tprintf(\"VxLAN checksum offload is %s\\n\",\n+\t\t(ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM) ? \"hw\" : \"sw\");\n+\n+\t/* display warnings if configuration is not supported by the NIC */\n+\trte_eth_dev_info_get(res->port_id, &dev_info);\n+\tif ((ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) &&\n+\t\t(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == 0) {\n+\t\tprintf(\"Warning: hardware IP checksum enabled but not \"\n+\t\t\t\"supported by port %d\\n\", res->port_id);\n+\t}\n+\tif ((ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) &&\n+\t\t(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM) == 0) {\n+\t\tprintf(\"Warning: hardware UDP checksum enabled but not \"\n+\t\t\t\"supported by port %d\\n\", res->port_id);\n+\t}\n+\tif ((ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) &&\n+\t\t(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM) == 0) {\n+\t\tprintf(\"Warning: hardware TCP checksum enabled but not \"\n+\t\t\t\"supported by port %d\\n\", res->port_id);\n+\t}\n+\tif ((ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) &&\n+\t\t(dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM) == 0) {\n+\t\tprintf(\"Warning: hardware SCTP checksum enabled but not \"\n+\t\t\t\"supported by port %d\\n\", res->port_id);\n+\t}\n }\n \n-cmdline_parse_token_string_t cmd_tx_cksum_set_tx_cksum =\n-\tTOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_set_result,\n+cmdline_parse_token_string_t cmd_tx_cksum_tx_cksum =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result,\n \t\t\t\ttx_cksum, \"tx_checksum\");\n-cmdline_parse_token_string_t cmd_tx_cksum_set_set =\n-\tTOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_set_result,\n-\t\t\t\tset, \"set\");\n-cmdline_parse_token_num_t cmd_tx_cksum_set_cksum_mask =\n-\tTOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_set_result,\n-\t\t\t\tcksum_mask, UINT8);\n-cmdline_parse_token_num_t cmd_tx_cksum_set_portid =\n-\tTOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_set_result,\n+cmdline_parse_token_string_t cmd_tx_cksum_mode =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result,\n+\t\t\t\tmode, \"set\");\n+cmdline_parse_token_string_t cmd_tx_cksum_proto =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result,\n+\t\t\t\tproto, \"ip#tcp#udp#sctp#vxlan\");\n+cmdline_parse_token_string_t cmd_tx_cksum_hwsw =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result,\n+\t\t\t\thwsw, \"hw#sw\");\n+cmdline_parse_token_num_t cmd_tx_cksum_portid =\n+\tTOKEN_NUM_INITIALIZER(struct cmd_tx_cksum_result,\n \t\t\t\tport_id, UINT8);\n \n cmdline_parse_inst_t cmd_tx_cksum_set = {\n-\t.f = cmd_tx_cksum_set_parsed,\n+\t.f = cmd_tx_cksum_parsed,\n+\t.data = NULL,\n+\t.help_str = \"enable/disable hardware calculation of L3/L4 checksum when \"\n+\t\t\"using csum forward engine: tx_cksum set ip|tcp|udp|sctp|vxlan hw|sw <port>\",\n+\t.tokens = {\n+\t\t(void *)&cmd_tx_cksum_tx_cksum,\n+\t\t(void *)&cmd_tx_cksum_mode,\n+\t\t(void *)&cmd_tx_cksum_proto,\n+\t\t(void *)&cmd_tx_cksum_hwsw,\n+\t\t(void *)&cmd_tx_cksum_portid,\n+\t\tNULL,\n+\t},\n+};\n+\n+cmdline_parse_token_string_t cmd_tx_cksum_mode_show =\n+\tTOKEN_STRING_INITIALIZER(struct cmd_tx_cksum_result,\n+\t\t\t\tmode, \"show\");\n+\n+cmdline_parse_inst_t cmd_tx_cksum_show = {\n+\t.f = cmd_tx_cksum_parsed,\n \t.data = NULL,\n-\t.help_str = \"enable hardware insertion of L3/L4checksum with a given \"\n-\t\"mask in packets sent on a port, the bit mapping is given as, Bit 0 for ip, \"\n-\t\"Bit 1 for UDP, Bit 2 for TCP, Bit 3 for SCTP, Bit 4 for inner ip, \"\n-\t\"Bit 5 for inner UDP, Bit 6 for inner TCP, Bit 7 for inner SCTP\",\n+\t.help_str = \"show checksum offload configuration: tx_cksum show <port>\",\n \t.tokens = {\n-\t\t(void *)&cmd_tx_cksum_set_tx_cksum,\n-\t\t(void *)&cmd_tx_cksum_set_set,\n-\t\t(void *)&cmd_tx_cksum_set_cksum_mask,\n-\t\t(void *)&cmd_tx_cksum_set_portid,\n+\t\t(void *)&cmd_tx_cksum_tx_cksum,\n+\t\t(void *)&cmd_tx_cksum_mode_show,\n+\t\t(void *)&cmd_tx_cksum_portid,\n \t\tNULL,\n \t},\n };\n@@ -7796,6 +7874,7 @@ cmdline_parse_ctx_t main_ctx[] = {\n \t(cmdline_parse_inst_t *)&cmd_tx_vlan_reset,\n \t(cmdline_parse_inst_t *)&cmd_tx_vlan_set_pvid,\n \t(cmdline_parse_inst_t *)&cmd_tx_cksum_set,\n+\t(cmdline_parse_inst_t *)&cmd_tx_cksum_show,\n \t(cmdline_parse_inst_t *)&cmd_link_flow_control_set,\n \t(cmdline_parse_inst_t *)&cmd_link_flow_control_set_rx,\n \t(cmdline_parse_inst_t *)&cmd_link_flow_control_set_tx,\ndiff --git a/app/test-pmd/config.c b/app/test-pmd/config.c\nindex 34b6fdb..16d62ab 100644\n--- a/app/test-pmd/config.c\n+++ b/app/test-pmd/config.c\n@@ -1744,17 +1744,6 @@ set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value)\n }\n \n void\n-tx_cksum_set(portid_t port_id, uint64_t ol_flags)\n-{\n-\tuint64_t tx_ol_flags;\n-\tif (port_id_is_invalid(port_id))\n-\t\treturn;\n-\t/* Clear last 8 bits and then set L3/4 checksum mask again */\n-\ttx_ol_flags = ports[port_id].tx_ol_flags & (~0x0FFull);\n-\tports[port_id].tx_ol_flags = ((ol_flags & 0xff) | tx_ol_flags);\n-}\n-\n-void\n fdir_add_signature_filter(portid_t port_id, uint8_t queue_id,\n \t\t\t  struct rte_fdir_filter *fdir_filter)\n {\ndiff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c\nindex 743094a..dda5d9e 100644\n--- a/app/test-pmd/csumonly.c\n+++ b/app/test-pmd/csumonly.c\n@@ -73,13 +73,19 @@\n #include <rte_string_fns.h>\n #include \"testpmd.h\"\n \n-\n-\n #define IP_DEFTTL  64   /* from RFC 1340. */\n #define IP_VERSION 0x40\n #define IP_HDRLEN  0x05 /* default IP header length == five 32-bits words. */\n #define IP_VHL_DEF (IP_VERSION | IP_HDRLEN)\n \n+/* we cannot use htons() from arpa/inet.h due to name conflicts, and we\n+ * cannot use rte_cpu_to_be_16() on a constant in a switch/case */\n+#if __BYTE_ORDER == __LITTLE_ENDIAN\n+#define _htons(x) ((uint16_t)((((x) & 0x00ffU) << 8) | (((x) & 0xff00U) >> 8)))\n+#else\n+#define _htons(x) (x)\n+#endif\n+\n static inline uint16_t\n get_16b_sum(uint16_t *ptr16, uint32_t nr)\n {\n@@ -112,7 +118,7 @@ get_ipv4_cksum(struct ipv4_hdr *ipv4_hdr)\n \n \n static inline uint16_t\n-get_ipv4_psd_sum (struct ipv4_hdr * ip_hdr)\n+get_ipv4_psd_sum(struct ipv4_hdr *ip_hdr)\n {\n \t/* Pseudo Header for IPv4/UDP/TCP checksum */\n \tunion ipv4_psd_header {\n@@ -136,7 +142,7 @@ get_ipv4_psd_sum (struct ipv4_hdr * ip_hdr)\n }\n \n static inline uint16_t\n-get_ipv6_psd_sum (struct ipv6_hdr * ip_hdr)\n+get_ipv6_psd_sum(struct ipv6_hdr *ip_hdr)\n {\n \t/* Pseudo Header for IPv6/UDP/TCP checksum */\n \tunion ipv6_psd_header {\n@@ -158,6 +164,15 @@ get_ipv6_psd_sum (struct ipv6_hdr * ip_hdr)\n \treturn get_16b_sum(psd_hdr.u16_arr, sizeof(psd_hdr));\n }\n \n+static uint16_t\n+get_psd_sum(void *l3_hdr, uint16_t ethertype)\n+{\n+\tif (ethertype == _htons(ETHER_TYPE_IPv4))\n+\t\treturn get_ipv4_psd_sum(l3_hdr);\n+\telse /* assume ethertype == ETHER_TYPE_IPv6 */\n+\t\treturn get_ipv6_psd_sum(l3_hdr);\n+}\n+\n static inline uint16_t\n get_ipv4_udptcp_checksum(struct ipv4_hdr *ipv4_hdr, uint16_t *l4_hdr)\n {\n@@ -174,7 +189,6 @@ get_ipv4_udptcp_checksum(struct ipv4_hdr *ipv4_hdr, uint16_t *l4_hdr)\n \tif (cksum == 0)\n \t\tcksum = 0xffff;\n \treturn (uint16_t)cksum;\n-\n }\n \n static inline uint16_t\n@@ -196,48 +210,218 @@ get_ipv6_udptcp_checksum(struct ipv6_hdr *ipv6_hdr, uint16_t *l4_hdr)\n \treturn (uint16_t)cksum;\n }\n \n+static uint16_t\n+get_udptcp_checksum(void *l3_hdr, void *l4_hdr, uint16_t ethertype)\n+{\n+\tif (ethertype == _htons(ETHER_TYPE_IPv4))\n+\t\treturn get_ipv4_udptcp_checksum(l3_hdr, l4_hdr);\n+\telse /* assume ethertype == ETHER_TYPE_IPv6 */\n+\t\treturn get_ipv6_udptcp_checksum(l3_hdr, l4_hdr);\n+}\n \n /*\n- * Forwarding of packets. Change the checksum field with HW or SW methods\n- * The HW/SW method selection depends on the ol_flags on every packet\n+ * Parse an ethernet header to fill the ethertype, l2_len, l3_len and\n+ * ipproto. This function is able to recognize IPv4/IPv6 with one optional vlan\n+ * header.\n+ */\n+static void\n+parse_ethernet(struct ether_hdr *eth_hdr, uint16_t *ethertype, uint16_t *l2_len,\n+\tuint16_t *l3_len, uint8_t *l4_proto)\n+{\n+\tstruct ipv4_hdr *ipv4_hdr;\n+\tstruct ipv6_hdr *ipv6_hdr;\n+\n+\t*l2_len = sizeof(struct ether_hdr);\n+\t*ethertype = eth_hdr->ether_type;\n+\n+\tif (*ethertype == _htons(ETHER_TYPE_VLAN)) {\n+\t\tstruct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);\n+\n+\t\t*l2_len  += sizeof(struct vlan_hdr);\n+\t\t*ethertype = vlan_hdr->eth_proto;\n+\t}\n+\n+\tswitch (*ethertype) {\n+\tcase _htons(ETHER_TYPE_IPv4):\n+\t\tipv4_hdr = (struct ipv4_hdr *) ((char *)eth_hdr + *l2_len);\n+\t\t*l3_len = (ipv4_hdr->version_ihl & 0x0f) * 4;\n+\t\t*l4_proto = ipv4_hdr->next_proto_id;\n+\t\tbreak;\n+\tcase _htons(ETHER_TYPE_IPv6):\n+\t\tipv6_hdr = (struct ipv6_hdr *) ((char *)eth_hdr + *l2_len);\n+\t\t*l3_len = sizeof(struct ipv6_hdr) ;\n+\t\t*l4_proto = ipv6_hdr->proto;\n+\t\tbreak;\n+\tdefault:\n+\t\t*l3_len = 0;\n+\t\t*l4_proto = 0;\n+\t\tbreak;\n+\t}\n+}\n+\n+/* modify the IPv4 or IPv4 source address of a packet */\n+static void\n+change_ip_addresses(void *l3_hdr, uint16_t ethertype)\n+{\n+\tstruct ipv4_hdr *ipv4_hdr = l3_hdr;\n+\tstruct ipv6_hdr *ipv6_hdr = l3_hdr;\n+\n+\tif (ethertype == _htons(ETHER_TYPE_IPv4)) {\n+\t\tipv4_hdr->src_addr =\n+\t\t\trte_cpu_to_be_32(rte_be_to_cpu_32(ipv4_hdr->src_addr) + 1);\n+\t}\n+\telse if (ethertype == _htons(ETHER_TYPE_IPv6)) {\n+\t\tipv6_hdr->src_addr[15] = ipv6_hdr->src_addr[15] + 1;\n+\t}\n+}\n+\n+/* if possible, calculate the checksum of a packet in hw or sw,\n+ * depending on the testpmd command line configuration */\n+static uint64_t\n+process_inner_cksums(void *l3_hdr, uint16_t ethertype, uint16_t l3_len,\n+\tuint8_t l4_proto, uint16_t testpmd_ol_flags)\n+{\n+\tstruct ipv4_hdr *ipv4_hdr = l3_hdr;\n+\tstruct udp_hdr *udp_hdr;\n+\tstruct tcp_hdr *tcp_hdr;\n+\tstruct sctp_hdr *sctp_hdr;\n+\tuint64_t ol_flags = 0;\n+\n+\tif (ethertype == _htons(ETHER_TYPE_IPv4)) {\n+\t\tipv4_hdr = l3_hdr;\n+\t\tipv4_hdr->hdr_checksum = 0;\n+\n+\t\tif (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM)\n+\t\t\tol_flags |= PKT_TX_IP_CKSUM;\n+\t\telse\n+\t\t\tipv4_hdr->hdr_checksum = get_ipv4_cksum(ipv4_hdr);\n+\n+\t}\n+\telse if (ethertype != _htons(ETHER_TYPE_IPv6))\n+\t\treturn 0; /* packet type not supported nothing to do */\n+\n+\tif (l4_proto == IPPROTO_UDP) {\n+\t\tudp_hdr = (struct udp_hdr *)((char *)l3_hdr + l3_len);\n+\t\t/* do not recalculate udp cksum if it was 0 */\n+\t\tif (udp_hdr->dgram_cksum != 0) {\n+\t\t\tudp_hdr->dgram_cksum = 0;\n+\t\t\tif (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) {\n+\t\t\t\tol_flags |= PKT_TX_UDP_CKSUM;\n+\t\t\t\tudp_hdr->dgram_cksum = get_psd_sum(l3_hdr,\n+\t\t\t\t\tethertype);\n+\t\t\t}\n+\t\t\telse {\n+\t\t\t\tudp_hdr->dgram_cksum =\n+\t\t\t\t\tget_udptcp_checksum(l3_hdr, udp_hdr,\n+\t\t\t\t\t\tethertype);\n+\t\t\t}\n+\t\t}\n+\t}\n+\telse if (l4_proto == IPPROTO_TCP) {\n+\t\ttcp_hdr = (struct tcp_hdr *)((char *)l3_hdr + l3_len);\n+\t\ttcp_hdr->cksum = 0;\n+\t\tif (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) {\n+\t\t\tol_flags |= PKT_TX_TCP_CKSUM;\n+\t\t\ttcp_hdr->cksum = get_psd_sum(l3_hdr, ethertype);\n+\t\t}\n+\t\telse {\n+\t\t\ttcp_hdr->cksum =\n+\t\t\t\tget_udptcp_checksum(l3_hdr, tcp_hdr, ethertype);\n+\t\t}\n+\t}\n+\telse if (l4_proto == IPPROTO_SCTP) {\n+\t\tsctp_hdr = (struct sctp_hdr *)((char *)l3_hdr + l3_len);\n+\t\tsctp_hdr->cksum = 0;\n+\t\t/* sctp payload must be a multiple of 4 to be\n+\t\t * offloaded */\n+\t\tif ((testpmd_ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) &&\n+\t\t\t((ipv4_hdr->total_length & 0x3) == 0)) {\n+\t\t\tol_flags |= PKT_TX_SCTP_CKSUM;\n+\t\t}\n+\t\telse {\n+\t\t\t/* XXX implement CRC32c, example available in\n+\t\t\t * RFC3309 */\n+\t\t}\n+\t}\n+\n+\treturn ol_flags;\n+}\n+\n+/* Calculate the checksum of outer header (only vxlan is supported,\n+ * meaning IP + UDP). The caller already checked that it's a vxlan\n+ * packet */\n+static uint64_t\n+process_outer_cksums(void *outer_l3_hdr, uint16_t outer_ethertype,\n+\tuint16_t outer_l3_len, uint16_t testpmd_ol_flags)\n+{\n+\tstruct ipv4_hdr *ipv4_hdr = outer_l3_hdr;\n+\tstruct ipv6_hdr *ipv6_hdr = outer_l3_hdr;\n+\tstruct udp_hdr *udp_hdr;\n+\tuint64_t ol_flags = 0;\n+\n+\tif (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM)\n+\t\tol_flags |= PKT_TX_VXLAN_CKSUM;\n+\n+\tif (outer_ethertype == _htons(ETHER_TYPE_IPv4)) {\n+\t\tipv4_hdr->hdr_checksum = 0;\n+\n+\t\tif ((testpmd_ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM) == 0)\n+\t\t\tipv4_hdr->hdr_checksum = get_ipv4_cksum(ipv4_hdr);\n+\t}\n+\n+\tudp_hdr = (struct udp_hdr *)((char *)outer_l3_hdr + outer_l3_len);\n+\t/* do not recalculate udp cksum if it was 0 */\n+\tif (udp_hdr->dgram_cksum != 0) {\n+\t\tudp_hdr->dgram_cksum = 0;\n+\t\tif ((testpmd_ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM) == 0) {\n+\t\t\tif (outer_ethertype == _htons(ETHER_TYPE_IPv4))\n+\t\t\t\tudp_hdr->dgram_cksum =\n+\t\t\t\t\tget_ipv4_udptcp_checksum(ipv4_hdr,\n+\t\t\t\t\t\t(uint16_t *)udp_hdr);\n+\t\t\telse\n+\t\t\t\tudp_hdr->dgram_cksum =\n+\t\t\t\t\tget_ipv6_udptcp_checksum(ipv6_hdr,\n+\t\t\t\t\t\t(uint16_t *)udp_hdr);\n+\t\t}\n+\t}\n+\n+\treturn ol_flags;\n+}\n+\n+/*\n+ * Receive a burst of packets, and for supported packet types:\n+ *  - modify the IPs\n+ *  - reprocess the checksum in SW or HW, depending on testpmd command line\n+ *    configuration\n+ * Then packets are transmitted on the output port.\n+ *\n+ * Supported packets are:\n+ *   Ether / (vlan) / IP|IP6 / UDP|TCP|SCTP .\n+ *   Ether / (vlan) / IP|IP6 / UDP / VxLAN / Ether / IP|IP6 / UDP|TCP|SCTP\n+ *\n+ * The network parser supposes that the packet is contiguous, which may\n+ * not be the case in real life.\n  */\n static void\n pkt_burst_checksum_forward(struct fwd_stream *fs)\n {\n-\tstruct rte_mbuf  *pkts_burst[MAX_PKT_BURST];\n-\tstruct rte_port  *txp;\n-\tstruct rte_mbuf  *mb;\n+\tstruct rte_mbuf *pkts_burst[MAX_PKT_BURST];\n+\tstruct rte_port *txp;\n+\tstruct rte_mbuf *m;\n \tstruct ether_hdr *eth_hdr;\n-\tstruct ipv4_hdr  *ipv4_hdr;\n-\tstruct ether_hdr *inner_eth_hdr;\n-\tstruct ipv4_hdr  *inner_ipv4_hdr = NULL;\n-\tstruct ipv6_hdr  *ipv6_hdr;\n-\tstruct ipv6_hdr  *inner_ipv6_hdr = NULL;\n-\tstruct udp_hdr   *udp_hdr;\n-\tstruct udp_hdr   *inner_udp_hdr;\n-\tstruct tcp_hdr   *tcp_hdr;\n-\tstruct tcp_hdr   *inner_tcp_hdr;\n-\tstruct sctp_hdr  *sctp_hdr;\n-\tstruct sctp_hdr  *inner_sctp_hdr;\n-\n+\tvoid *l3_hdr = NULL, *outer_l3_hdr = NULL; /* can be IPv4 or IPv6 */\n+\tstruct udp_hdr *udp_hdr;\n \tuint16_t nb_rx;\n \tuint16_t nb_tx;\n \tuint16_t i;\n \tuint64_t ol_flags;\n-\tuint64_t pkt_ol_flags;\n-\tuint64_t tx_ol_flags;\n-\tuint16_t l4_proto;\n-\tuint16_t inner_l4_proto = 0;\n-\tuint16_t eth_type;\n-\tuint8_t  l2_len;\n-\tuint8_t  l3_len;\n-\tuint8_t  inner_l2_len = 0;\n-\tuint8_t  inner_l3_len = 0;\n-\n+\tuint16_t testpmd_ol_flags;\n+\tuint8_t l4_proto;\n+\tuint16_t ethertype = 0, outer_ethertype = 0;\n+\tuint16_t  l2_len = 0, l3_len = 0, outer_l2_len = 0, outer_l3_len = 0;\n+\tint tunnel = 0;\n \tuint32_t rx_bad_ip_csum;\n \tuint32_t rx_bad_l4_csum;\n-\tuint8_t  ipv4_tunnel;\n-\tuint8_t  ipv6_tunnel;\n \n #ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES\n \tuint64_t start_tsc;\n@@ -249,9 +433,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)\n \tstart_tsc = rte_rdtsc();\n #endif\n \n-\t/*\n-\t * Receive a burst of packets and forward them.\n-\t */\n+\t/* receive a burst of packet */\n \tnb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,\n \t\t\t\t nb_pkt_per_burst);\n \tif (unlikely(nb_rx == 0))\n@@ -265,348 +447,107 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)\n \trx_bad_l4_csum = 0;\n \n \ttxp = &ports[fs->tx_port];\n-\ttx_ol_flags = txp->tx_ol_flags;\n+\ttestpmd_ol_flags = txp->tx_ol_flags;\n \n \tfor (i = 0; i < nb_rx; i++) {\n \n-\t\tmb = pkts_burst[i];\n-\t\tl2_len  = sizeof(struct ether_hdr);\n-\t\tpkt_ol_flags = mb->ol_flags;\n-\t\tol_flags = (pkt_ol_flags & (~PKT_TX_L4_MASK));\n-\t\tipv4_tunnel = (pkt_ol_flags & PKT_RX_TUNNEL_IPV4_HDR) ?\n-\t\t\t\t1 : 0;\n-\t\tipv6_tunnel = (pkt_ol_flags & PKT_RX_TUNNEL_IPV6_HDR) ?\n-\t\t\t\t1 : 0;\n-\t\teth_hdr = rte_pktmbuf_mtod(mb, struct ether_hdr *);\n-\t\teth_type = rte_be_to_cpu_16(eth_hdr->ether_type);\n-\t\tif (eth_type == ETHER_TYPE_VLAN) {\n-\t\t\t/* Only allow single VLAN label here */\n-\t\t\tl2_len  += sizeof(struct vlan_hdr);\n-\t\t\t eth_type = rte_be_to_cpu_16(*(uint16_t *)\n-\t\t\t\t((uintptr_t)&eth_hdr->ether_type +\n-\t\t\t\tsizeof(struct vlan_hdr)));\n+\t\tol_flags = 0;\n+\t\ttunnel = 0;\n+\t\tm = pkts_burst[i];\n+\n+\t\t/* Update the L3/L4 checksum error packet statistics */\n+\t\trx_bad_ip_csum += ((m->ol_flags & PKT_RX_IP_CKSUM_BAD) != 0);\n+\t\trx_bad_l4_csum += ((m->ol_flags & PKT_RX_L4_CKSUM_BAD) != 0);\n+\n+\t\t/* step 1: dissect packet, parsing optional vlan, ip4/ip6, vxlan\n+\t\t * and inner headers */\n+\n+\t\teth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);\n+\t\tparse_ethernet(eth_hdr, &ethertype, &l2_len, &l3_len, &l4_proto);\n+\t\tl3_hdr = (char *)eth_hdr + l2_len;\n+\n+\t\t/* check if it's a supported tunnel (only vxlan for now) */\n+\t\tif (l4_proto == IPPROTO_UDP) {\n+\t\t\tudp_hdr = (struct udp_hdr *)((char *)l3_hdr + l3_len);\n+\n+\t\t\t/* currently, this flag is set by i40e only if the\n+\t\t\t * packet is vxlan */\n+\t\t\tif (((m->ol_flags & PKT_RX_TUNNEL_IPV4_HDR) ||\n+\t\t\t\t\t(m->ol_flags & PKT_RX_TUNNEL_IPV6_HDR)))\n+\t\t\t\ttunnel = 1;\n+\t\t\t/* else check udp destination port, 4789 is the default\n+\t\t\t * vxlan port (rfc7348) */\n+\t\t\telse if (udp_hdr->dst_port == _htons(4789))\n+\t\t\t\ttunnel = 1;\n+\n+\t\t\tif (tunnel == 1) {\n+\t\t\t\touter_ethertype = ethertype;\n+\t\t\t\touter_l2_len = l2_len;\n+\t\t\t\touter_l3_len = l3_len;\n+\t\t\t\touter_l3_hdr = l3_hdr;\n+\n+\t\t\t\teth_hdr = (struct ether_hdr *)((char *)udp_hdr +\n+\t\t\t\t\tsizeof(struct udp_hdr) +\n+\t\t\t\t\tsizeof(struct vxlan_hdr));\n+\n+\t\t\t\tparse_ethernet(eth_hdr, &ethertype, &l2_len,\n+\t\t\t\t\t&l3_len, &l4_proto);\n+\t\t\t\tl3_hdr = (char *)eth_hdr + l2_len;\n+\t\t\t}\n \t\t}\n \n-\t\t/* Update the L3/L4 checksum error packet count  */\n-\t\trx_bad_ip_csum += (uint16_t) ((pkt_ol_flags & PKT_RX_IP_CKSUM_BAD) != 0);\n-\t\trx_bad_l4_csum += (uint16_t) ((pkt_ol_flags & PKT_RX_L4_CKSUM_BAD) != 0);\n-\n-\t\t/*\n-\t\t * Try to figure out L3 packet type by SW.\n-\t\t */\n-\t\tif ((pkt_ol_flags & (PKT_RX_IPV4_HDR | PKT_RX_IPV4_HDR_EXT |\n-\t\t\t\tPKT_RX_IPV6_HDR | PKT_RX_IPV6_HDR_EXT)) == 0) {\n-\t\t\tif (eth_type == ETHER_TYPE_IPv4)\n-\t\t\t\tpkt_ol_flags |= PKT_RX_IPV4_HDR;\n-\t\t\telse if (eth_type == ETHER_TYPE_IPv6)\n-\t\t\t\tpkt_ol_flags |= PKT_RX_IPV6_HDR;\n-\t\t}\n+\t\t/* step 2: change all source IPs (v4 or v6) so we need\n+\t\t * to recompute the chksums even if they were correct */\n \n-\t\t/*\n-\t\t * Simplify the protocol parsing\n-\t\t * Assuming the incoming packets format as\n-\t\t *      Ethernet2 + optional single VLAN\n-\t\t *      + ipv4 or ipv6\n-\t\t *      + udp or tcp or sctp or others\n-\t\t */\n-\t\tif (pkt_ol_flags & (PKT_RX_IPV4_HDR | PKT_RX_TUNNEL_IPV4_HDR)) {\n+\t\tchange_ip_addresses(l3_hdr, ethertype);\n+\t\tif (tunnel == 1)\n+\t\t\tchange_ip_addresses(outer_l3_hdr, outer_ethertype);\n \n-\t\t\t/* Do not support ipv4 option field */\n-\t\t\tl3_len = sizeof(struct ipv4_hdr) ;\n+\t\t/* step 3: depending on user command line configuration,\n+\t\t * recompute checksum either in software or flag the\n+\t\t * mbuf to offload the calculation to the NIC */\n \n-\t\t\tipv4_hdr = (struct ipv4_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\tunsigned char *) + l2_len);\n+\t\t/* process checksums of inner headers first */\n+\t\tol_flags |= process_inner_cksums(l3_hdr, ethertype,\n+\t\t\tl3_len, l4_proto, testpmd_ol_flags);\n \n-\t\t\tl4_proto = ipv4_hdr->next_proto_id;\n+\t\t/* Then process outer headers if any. Note that the software\n+\t\t * checksum will be wrong if one of the inner checksums is\n+\t\t * processed in hardware. */\n+\t\tif (tunnel == 1) {\n+\t\t\tol_flags |= process_outer_cksums(outer_l3_hdr,\n+\t\t\t\touter_ethertype, outer_l3_len, testpmd_ol_flags);\n+\t\t}\n \n-\t\t\t/* Do not delete, this is required by HW*/\n-\t\t\tipv4_hdr->hdr_checksum = 0;\n+\t\t/* step 4: fill the mbuf meta data (flags and header lengths) */\n \n-\t\t\tif (tx_ol_flags & TESTPMD_TX_OFFLOAD_IP_CKSUM) {\n-\t\t\t\t/* HW checksum */\n-\t\t\t\tol_flags |= PKT_TX_IP_CKSUM;\n+\t\tif (tunnel == 1) {\n+\t\t\tif (testpmd_ol_flags & TESTPMD_TX_OFFLOAD_VXLAN_CKSUM) {\n+\t\t\t\tm->l2_len = outer_l2_len;\n+\t\t\t\tm->l3_len = outer_l3_len;\n+\t\t\t\tm->inner_l2_len = l2_len;\n+\t\t\t\tm->inner_l3_len = l3_len;\n \t\t\t}\n \t\t\telse {\n-\t\t\t\tol_flags |= PKT_TX_IPV4;\n-\t\t\t\t/* SW checksum calculation */\n-\t\t\t\tipv4_hdr->src_addr++;\n-\t\t\t\tipv4_hdr->hdr_checksum = get_ipv4_cksum(ipv4_hdr);\n+\t\t\t\t/* if we don't do vxlan cksum in hw,\n+\t\t\t\t   outer checksum will be wrong because\n+\t\t\t\t   we changed the ip, but it shows that\n+\t\t\t\t   we can process the inner header cksum\n+\t\t\t\t   in the nic */\n+\t\t\t\tm->l2_len = outer_l2_len + outer_l3_len +\n+\t\t\t\t\tsizeof(struct udp_hdr) +\n+\t\t\t\t\tsizeof(struct vxlan_hdr) + l2_len;\n+\t\t\t\tm->l3_len = l3_len;\n \t\t\t}\n-\n-\t\t\tif (l4_proto == IPPROTO_UDP) {\n-\t\t\t\tudp_hdr = (struct udp_hdr*) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\tunsigned char *) + l2_len + l3_len);\n-\t\t\t\tif (tx_ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) {\n-\t\t\t\t\t/* HW Offload */\n-\t\t\t\t\tol_flags |= PKT_TX_UDP_CKSUM;\n-\t\t\t\t\tif (ipv4_tunnel)\n-\t\t\t\t\t\tudp_hdr->dgram_cksum = 0;\n-\t\t\t\t\telse\n-\t\t\t\t\t\t/* Pseudo header sum need be set properly */\n-\t\t\t\t\t\tudp_hdr->dgram_cksum =\n-\t\t\t\t\t\t\tget_ipv4_psd_sum(ipv4_hdr);\n-\t\t\t\t}\n-\t\t\t\telse {\n-\t\t\t\t\t/* SW Implementation, clear checksum field first */\n-\t\t\t\t\tudp_hdr->dgram_cksum = 0;\n-\t\t\t\t\tudp_hdr->dgram_cksum = get_ipv4_udptcp_checksum(ipv4_hdr,\n-\t\t\t\t\t\t\t\t\t(uint16_t *)udp_hdr);\n-\t\t\t\t}\n-\n-\t\t\t\tif (ipv4_tunnel) {\n-\n-\t\t\t\t\tuint16_t len;\n-\n-\t\t\t\t\t/* Check if inner L3/L4 checkum flag is set */\n-\t\t\t\t\tif (tx_ol_flags & TESTPMD_TX_OFFLOAD_INNER_CKSUM_MASK)\n-\t\t\t\t\t\tol_flags |= PKT_TX_VXLAN_CKSUM;\n-\n-\t\t\t\t\tinner_l2_len  = sizeof(struct ether_hdr);\n-\t\t\t\t\tinner_eth_hdr = (struct ether_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\t\t\tunsigned char *) + l2_len + l3_len\n-\t\t\t\t\t\t\t\t + ETHER_VXLAN_HLEN);\n-\n-\t\t\t\t\teth_type = rte_be_to_cpu_16(inner_eth_hdr->ether_type);\n-\t\t\t\t\tif (eth_type == ETHER_TYPE_VLAN) {\n-\t\t\t\t\t\tinner_l2_len += sizeof(struct vlan_hdr);\n-\t\t\t\t\t\teth_type = rte_be_to_cpu_16(*(uint16_t *)\n-\t\t\t\t\t\t\t((uintptr_t)&eth_hdr->ether_type +\n-\t\t\t\t\t\t\t\tsizeof(struct vlan_hdr)));\n-\t\t\t\t\t}\n-\n-\t\t\t\t\tlen = l2_len + l3_len + ETHER_VXLAN_HLEN + inner_l2_len;\n-\t\t\t\t\tif (eth_type == ETHER_TYPE_IPv4) {\n-\t\t\t\t\t\tinner_l3_len = sizeof(struct ipv4_hdr);\n-\t\t\t\t\t\tinner_ipv4_hdr = (struct ipv4_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\t\t\tunsigned char *) + len);\n-\t\t\t\t\t\tinner_l4_proto = inner_ipv4_hdr->next_proto_id;\n-\n-\t\t\t\t\t\tif (tx_ol_flags & TESTPMD_TX_OFFLOAD_INNER_IP_CKSUM) {\n-\n-\t\t\t\t\t\t\t/* Do not delete, this is required by HW*/\n-\t\t\t\t\t\t\tinner_ipv4_hdr->hdr_checksum = 0;\n-\t\t\t\t\t\t\tol_flags |= PKT_TX_IPV4_CSUM;\n-\t\t\t\t\t\t}\n-\n-\t\t\t\t\t} else if (eth_type == ETHER_TYPE_IPv6) {\n-\t\t\t\t\t\tinner_l3_len = sizeof(struct ipv6_hdr);\n-\t\t\t\t\t\tinner_ipv6_hdr = (struct ipv6_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\t\t\tunsigned char *) + len);\n-\t\t\t\t\t\tinner_l4_proto = inner_ipv6_hdr->proto;\n-\t\t\t\t\t}\n-\t\t\t\t\tif ((inner_l4_proto == IPPROTO_UDP) &&\n-\t\t\t\t\t\t(tx_ol_flags & TESTPMD_TX_OFFLOAD_INNER_UDP_CKSUM)) {\n-\n-\t\t\t\t\t\t/* HW Offload */\n-\t\t\t\t\t\tol_flags |= PKT_TX_UDP_CKSUM;\n-\t\t\t\t\t\tinner_udp_hdr = (struct udp_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\t\t\tunsigned char *) + len + inner_l3_len);\n-\t\t\t\t\t\tif (eth_type == ETHER_TYPE_IPv4)\n-\t\t\t\t\t\t\tinner_udp_hdr->dgram_cksum = get_ipv4_psd_sum(inner_ipv4_hdr);\n-\t\t\t\t\t\telse if (eth_type == ETHER_TYPE_IPv6)\n-\t\t\t\t\t\t\tinner_udp_hdr->dgram_cksum = get_ipv6_psd_sum(inner_ipv6_hdr);\n-\n-\t\t\t\t\t} else if ((inner_l4_proto == IPPROTO_TCP) &&\n-\t\t\t\t\t\t(tx_ol_flags & TESTPMD_TX_OFFLOAD_INNER_TCP_CKSUM)) {\n-\t\t\t\t\t\t/* HW Offload */\n-\t\t\t\t\t\tol_flags |= PKT_TX_TCP_CKSUM;\n-\t\t\t\t\t\tinner_tcp_hdr = (struct tcp_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\t\t\tunsigned char *) + len + inner_l3_len);\n-\t\t\t\t\t\tif (eth_type == ETHER_TYPE_IPv4)\n-\t\t\t\t\t\t\tinner_tcp_hdr->cksum = get_ipv4_psd_sum(inner_ipv4_hdr);\n-\t\t\t\t\t\telse if (eth_type == ETHER_TYPE_IPv6)\n-\t\t\t\t\t\t\tinner_tcp_hdr->cksum = get_ipv6_psd_sum(inner_ipv6_hdr);\n-\t\t\t\t\t} else if ((inner_l4_proto == IPPROTO_SCTP) &&\n-\t\t\t\t\t\t(tx_ol_flags & TESTPMD_TX_OFFLOAD_INNER_SCTP_CKSUM)) {\n-\t\t\t\t\t\t/* HW Offload */\n-\t\t\t\t\t\tol_flags |= PKT_TX_SCTP_CKSUM;\n-\t\t\t\t\t\tinner_sctp_hdr = (struct sctp_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\t\t\tunsigned char *) + len + inner_l3_len);\n-\t\t\t\t\t\tinner_sctp_hdr->cksum = 0;\n-\t\t\t\t\t}\n-\n-\t\t\t\t}\n-\n-\t\t\t} else if (l4_proto == IPPROTO_TCP) {\n-\t\t\t\ttcp_hdr = (struct tcp_hdr*) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\tunsigned char *) + l2_len + l3_len);\n-\t\t\t\tif (tx_ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) {\n-\t\t\t\t\tol_flags |= PKT_TX_TCP_CKSUM;\n-\t\t\t\t\ttcp_hdr->cksum = get_ipv4_psd_sum(ipv4_hdr);\n-\t\t\t\t}\n-\t\t\t\telse {\n-\t\t\t\t\ttcp_hdr->cksum = 0;\n-\t\t\t\t\ttcp_hdr->cksum = get_ipv4_udptcp_checksum(ipv4_hdr,\n-\t\t\t\t\t\t\t(uint16_t*)tcp_hdr);\n-\t\t\t\t}\n-\t\t\t} else if (l4_proto == IPPROTO_SCTP) {\n-\t\t\t\tsctp_hdr = (struct sctp_hdr*) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\tunsigned char *) + l2_len + l3_len);\n-\n-\t\t\t\tif (tx_ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) {\n-\t\t\t\t\tol_flags |= PKT_TX_SCTP_CKSUM;\n-\t\t\t\t\tsctp_hdr->cksum = 0;\n-\n-\t\t\t\t\t/* Sanity check, only number of 4 bytes supported */\n-\t\t\t\t\tif ((rte_be_to_cpu_16(ipv4_hdr->total_length) % 4) != 0)\n-\t\t\t\t\t\tprintf(\"sctp payload must be a multiple \"\n-\t\t\t\t\t\t\t\"of 4 bytes for checksum offload\");\n-\t\t\t\t}\n-\t\t\t\telse {\n-\t\t\t\t\tsctp_hdr->cksum = 0;\n-\t\t\t\t\t/* CRC32c sample code available in RFC3309 */\n-\t\t\t\t}\n-\t\t\t}\n-\t\t\t/* End of L4 Handling*/\n-\t\t} else if (pkt_ol_flags & (PKT_RX_IPV6_HDR | PKT_RX_TUNNEL_IPV6_HDR)) {\n-\t\t\tipv6_hdr = (struct ipv6_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\tunsigned char *) + l2_len);\n-\t\t\tl3_len = sizeof(struct ipv6_hdr) ;\n-\t\t\tl4_proto = ipv6_hdr->proto;\n-\t\t\tol_flags |= PKT_TX_IPV6;\n-\n-\t\t\tif (l4_proto == IPPROTO_UDP) {\n-\t\t\t\tudp_hdr = (struct udp_hdr*) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\tunsigned char *) + l2_len + l3_len);\n-\t\t\t\tif (tx_ol_flags & TESTPMD_TX_OFFLOAD_UDP_CKSUM) {\n-\t\t\t\t\t/* HW Offload */\n-\t\t\t\t\tol_flags |= PKT_TX_UDP_CKSUM;\n-\t\t\t\t\tif (ipv6_tunnel)\n-\t\t\t\t\t\tudp_hdr->dgram_cksum = 0;\n-\t\t\t\t\telse\n-\t\t\t\t\t\tudp_hdr->dgram_cksum =\n-\t\t\t\t\t\t\tget_ipv6_psd_sum(ipv6_hdr);\n-\t\t\t\t}\n-\t\t\t\telse {\n-\t\t\t\t\t/* SW Implementation */\n-\t\t\t\t\t/* checksum field need be clear first */\n-\t\t\t\t\tudp_hdr->dgram_cksum = 0;\n-\t\t\t\t\tudp_hdr->dgram_cksum = get_ipv6_udptcp_checksum(ipv6_hdr,\n-\t\t\t\t\t\t\t\t(uint16_t *)udp_hdr);\n-\t\t\t\t}\n-\n-\t\t\t\tif (ipv6_tunnel) {\n-\n-\t\t\t\t\tuint16_t len;\n-\n-\t\t\t\t\t/* Check if inner L3/L4 checksum flag is set */\n-\t\t\t\t\tif (tx_ol_flags & TESTPMD_TX_OFFLOAD_INNER_CKSUM_MASK)\n-\t\t\t\t\t\tol_flags |= PKT_TX_VXLAN_CKSUM;\n-\n-\t\t\t\t\tinner_l2_len  = sizeof(struct ether_hdr);\n-\t\t\t\t\tinner_eth_hdr = (struct ether_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\tunsigned char *) + l2_len + l3_len + ETHER_VXLAN_HLEN);\n-\t\t\t\t\teth_type = rte_be_to_cpu_16(inner_eth_hdr->ether_type);\n-\n-\t\t\t\t\tif (eth_type == ETHER_TYPE_VLAN) {\n-\t\t\t\t\t\tinner_l2_len += sizeof(struct vlan_hdr);\n-\t\t\t\t\t\teth_type = rte_be_to_cpu_16(*(uint16_t *)\n-\t\t\t\t\t\t\t((uintptr_t)&eth_hdr->ether_type +\n-\t\t\t\t\t\t\tsizeof(struct vlan_hdr)));\n-\t\t\t\t\t}\n-\n-\t\t\t\t\tlen = l2_len + l3_len + ETHER_VXLAN_HLEN + inner_l2_len;\n-\n-\t\t\t\t\tif (eth_type == ETHER_TYPE_IPv4) {\n-\t\t\t\t\t\tinner_l3_len = sizeof(struct ipv4_hdr);\n-\t\t\t\t\t\tinner_ipv4_hdr = (struct ipv4_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\t\t\tunsigned char *) + len);\n-\t\t\t\t\t\tinner_l4_proto = inner_ipv4_hdr->next_proto_id;\n-\n-\t\t\t\t\t\t/* HW offload */\n-\t\t\t\t\t\tif (tx_ol_flags & TESTPMD_TX_OFFLOAD_INNER_IP_CKSUM) {\n-\n-\t\t\t\t\t\t\t/* Do not delete, this is required by HW*/\n-\t\t\t\t\t\t\tinner_ipv4_hdr->hdr_checksum = 0;\n-\t\t\t\t\t\t\tol_flags |= PKT_TX_IPV4_CSUM;\n-\t\t\t\t\t\t}\n-\t\t\t\t\t} else if (eth_type == ETHER_TYPE_IPv6) {\n-\t\t\t\t\t\tinner_l3_len = sizeof(struct ipv6_hdr);\n-\t\t\t\t\t\tinner_ipv6_hdr = (struct ipv6_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\t\tunsigned char *) + len);\n-\t\t\t\t\t\tinner_l4_proto = inner_ipv6_hdr->proto;\n-\t\t\t\t\t}\n-\n-\t\t\t\t\tif ((inner_l4_proto == IPPROTO_UDP) &&\n-\t\t\t\t\t\t(tx_ol_flags & TESTPMD_TX_OFFLOAD_INNER_UDP_CKSUM)) {\n-\t\t\t\t\t\tinner_udp_hdr = (struct udp_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\t\tunsigned char *) + len + inner_l3_len);\n-\t\t\t\t\t\t/* HW offload */\n-\t\t\t\t\t\tol_flags |= PKT_TX_UDP_CKSUM;\n-\t\t\t\t\t\tinner_udp_hdr->dgram_cksum = 0;\n-\t\t\t\t\t\tif (eth_type == ETHER_TYPE_IPv4)\n-\t\t\t\t\t\t\tinner_udp_hdr->dgram_cksum = get_ipv4_psd_sum(inner_ipv4_hdr);\n-\t\t\t\t\t\telse if (eth_type == ETHER_TYPE_IPv6)\n-\t\t\t\t\t\t\tinner_udp_hdr->dgram_cksum = get_ipv6_psd_sum(inner_ipv6_hdr);\n-\t\t\t\t\t} else if ((inner_l4_proto == IPPROTO_TCP) &&\n-\t\t\t\t\t\t(tx_ol_flags & TESTPMD_TX_OFFLOAD_INNER_TCP_CKSUM)) {\n-\t\t\t\t\t\t/* HW offload */\n-\t\t\t\t\t\tol_flags |= PKT_TX_TCP_CKSUM;\n-\t\t\t\t\t\tinner_tcp_hdr = (struct tcp_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\t\t\tunsigned char *) + len + inner_l3_len);\n-\n-\t\t\t\t\t\tif (eth_type == ETHER_TYPE_IPv4)\n-\t\t\t\t\t\t\tinner_tcp_hdr->cksum = get_ipv4_psd_sum(inner_ipv4_hdr);\n-\t\t\t\t\t\telse if (eth_type == ETHER_TYPE_IPv6)\n-\t\t\t\t\t\t\tinner_tcp_hdr->cksum = get_ipv6_psd_sum(inner_ipv6_hdr);\n-\n-\t\t\t\t\t} else if ((inner_l4_proto == IPPROTO_SCTP) &&\n-\t\t\t\t\t\t(tx_ol_flags & TESTPMD_TX_OFFLOAD_INNER_SCTP_CKSUM)) {\n-\t\t\t\t\t\t/* HW offload */\n-\t\t\t\t\t\tol_flags |= PKT_TX_SCTP_CKSUM;\n-\t\t\t\t\t\tinner_sctp_hdr = (struct sctp_hdr *) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\t\t\tunsigned char *) + len + inner_l3_len);\n-\t\t\t\t\t\tinner_sctp_hdr->cksum = 0;\n-\t\t\t\t\t}\n-\n-\t\t\t\t}\n-\n-\t\t\t}\n-\t\t\telse if (l4_proto == IPPROTO_TCP) {\n-\t\t\t\ttcp_hdr = (struct tcp_hdr*) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\tunsigned char *) + l2_len + l3_len);\n-\t\t\t\tif (tx_ol_flags & TESTPMD_TX_OFFLOAD_TCP_CKSUM) {\n-\t\t\t\t\tol_flags |= PKT_TX_TCP_CKSUM;\n-\t\t\t\t\ttcp_hdr->cksum = get_ipv6_psd_sum(ipv6_hdr);\n-\t\t\t\t}\n-\t\t\t\telse {\n-\t\t\t\t\ttcp_hdr->cksum = 0;\n-\t\t\t\t\ttcp_hdr->cksum = get_ipv6_udptcp_checksum(ipv6_hdr,\n-\t\t\t\t\t\t\t(uint16_t*)tcp_hdr);\n-\t\t\t\t}\n-\t\t\t}\n-\t\t\telse if (l4_proto == IPPROTO_SCTP) {\n-\t\t\t\tsctp_hdr = (struct sctp_hdr*) (rte_pktmbuf_mtod(mb,\n-\t\t\t\t\t\tunsigned char *) + l2_len + l3_len);\n-\n-\t\t\t\tif (tx_ol_flags & TESTPMD_TX_OFFLOAD_SCTP_CKSUM) {\n-\t\t\t\t\tol_flags |= PKT_TX_SCTP_CKSUM;\n-\t\t\t\t\tsctp_hdr->cksum = 0;\n-\t\t\t\t\t/* Sanity check, only number of 4 bytes supported by HW */\n-\t\t\t\t\tif ((rte_be_to_cpu_16(ipv6_hdr->payload_len) % 4) != 0)\n-\t\t\t\t\t\tprintf(\"sctp payload must be a multiple \"\n-\t\t\t\t\t\t\t\"of 4 bytes for checksum offload\");\n-\t\t\t\t}\n-\t\t\t\telse {\n-\t\t\t\t\t/* CRC32c sample code available in RFC3309 */\n-\t\t\t\t\tsctp_hdr->cksum = 0;\n-\t\t\t\t}\n-\t\t\t} else {\n-\t\t\t\tprintf(\"Test flow control for 1G PMD \\n\");\n-\t\t\t}\n-\t\t\t/* End of L6 Handling*/\n-\t\t}\n-\t\telse {\n-\t\t\tl3_len = 0;\n-\t\t\tprintf(\"Unhandled packet type: %#hx\\n\", eth_type);\n+\t\t} else {\n+\t\t\t/* this is only useful if an offload flag is\n+\t\t\t * set, but it does not hurt to fill it in any\n+\t\t\t * case */\n+\t\t\tm->l2_len = l2_len;\n+\t\t\tm->l3_len = l3_len;\n \t\t}\n+\t\tm->ol_flags = ol_flags;\n \n-\t\t/* Combine the packet header write. VLAN is not consider here */\n-\t\tmb->l2_len = l2_len;\n-\t\tmb->l3_len = l3_len;\n-\t\tmb->inner_l2_len = inner_l2_len;\n-\t\tmb->inner_l3_len = inner_l3_len;\n-\t\tmb->ol_flags = ol_flags;\n \t}\n \tnb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);\n \tfs->tx_packets += nb_tx;\n@@ -629,7 +570,6 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)\n #endif\n }\n \n-\n struct fwd_engine csum_fwd_engine = {\n \t.fwd_mode_name  = \"csum\",\n \t.port_fwd_begin = NULL,\ndiff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h\nindex 82af2bd..c753d37 100644\n--- a/app/test-pmd/testpmd.h\n+++ b/app/test-pmd/testpmd.h\n@@ -131,18 +131,11 @@ struct fwd_stream {\n #define TESTPMD_TX_OFFLOAD_TCP_CKSUM         0x0004\n /** Offload SCTP checksum in csum forward engine */\n #define TESTPMD_TX_OFFLOAD_SCTP_CKSUM        0x0008\n-/** Offload inner IP checksum in csum forward engine */\n-#define TESTPMD_TX_OFFLOAD_INNER_IP_CKSUM    0x0010\n-/** Offload inner UDP checksum in csum forward engine */\n-#define TESTPMD_TX_OFFLOAD_INNER_UDP_CKSUM   0x0020\n-/** Offload inner TCP checksum in csum forward engine */\n-#define TESTPMD_TX_OFFLOAD_INNER_TCP_CKSUM   0x0040\n-/** Offload inner SCTP checksum in csum forward engine */\n-#define TESTPMD_TX_OFFLOAD_INNER_SCTP_CKSUM  0x0080\n-/** Offload inner IP checksum mask */\n-#define TESTPMD_TX_OFFLOAD_INNER_CKSUM_MASK  0x00F0\n+/** Offload VxLAN checksum in csum forward engine */\n+#define TESTPMD_TX_OFFLOAD_VXLAN_CKSUM       0x0010\n /** Insert VLAN header in forward engine */\n-#define TESTPMD_TX_OFFLOAD_INSERT_VLAN       0x0100\n+#define TESTPMD_TX_OFFLOAD_INSERT_VLAN       0x0020\n+\n /**\n  * The data structure associated with each port.\n  */\n@@ -510,8 +503,6 @@ void tx_vlan_pvid_set(portid_t port_id, uint16_t vlan_id, int on);\n \n void set_qmap(portid_t port_id, uint8_t is_rx, uint16_t queue_id, uint8_t map_value);\n \n-void tx_cksum_set(portid_t port_id, uint64_t ol_flags);\n-\n void set_verbose_level(uint16_t vb_level);\n void set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs);\n void set_nb_pkt_per_burst(uint16_t pkt_burst);\n",
    "prefixes": [
        "dpdk-dev",
        "v2",
        "08/13"
    ]
}