get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 47672,
    "url": "http://patches.dpdk.org/api/patches/47672/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1541074741-41368-13-git-send-email-viacheslavo@mellanox.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": "<1541074741-41368-13-git-send-email-viacheslavo@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1541074741-41368-13-git-send-email-viacheslavo@mellanox.com",
    "date": "2018-11-01T12:19:34",
    "name": "[v3,12/13] net/mlx5: add e-switch VXLAN encapsulation rules",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "3d74cecba180dc115c917a63388a78ed676acd72",
    "submitter": {
        "id": 1102,
        "url": "http://patches.dpdk.org/api/people/1102/?format=api",
        "name": "Slava Ovsiienko",
        "email": "viacheslavo@mellanox.com"
    },
    "delegate": {
        "id": 6624,
        "url": "http://patches.dpdk.org/api/users/6624/?format=api",
        "username": "shahafs",
        "first_name": "Shahaf",
        "last_name": "Shuler",
        "email": "shahafs@mellanox.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1541074741-41368-13-git-send-email-viacheslavo@mellanox.com/mbox/",
    "series": [
        {
            "id": 2204,
            "url": "http://patches.dpdk.org/api/series/2204/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=2204",
            "date": "2018-11-01T12:19:21",
            "name": "net/mlx5: e-switch VXLAN encap/decap hardware offload",
            "version": 3,
            "mbox": "http://patches.dpdk.org/series/2204/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/47672/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/47672/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 [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id 252321B275;\n\tThu,  1 Nov 2018 13:19:45 +0100 (CET)",
            "from EUR03-AM5-obe.outbound.protection.outlook.com\n\t(mail-eopbgr30084.outbound.protection.outlook.com [40.107.3.84])\n\tby dpdk.org (Postfix) with ESMTP id C3A3A1B1DD\n\tfor <dev@dpdk.org>; Thu,  1 Nov 2018 13:19:35 +0100 (CET)",
            "from AM4PR05MB3265.eurprd05.prod.outlook.com (10.171.186.150) by\n\tAM4PR05MB1457.eurprd05.prod.outlook.com (10.164.79.27) with Microsoft\n\tSMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.1273.20; Thu, 1 Nov 2018 12:19:34 +0000",
            "from AM4PR05MB3265.eurprd05.prod.outlook.com\n\t([fe80::544b:a68d:e6a5:ba6e]) by\n\tAM4PR05MB3265.eurprd05.prod.outlook.com\n\t([fe80::544b:a68d:e6a5:ba6e%2]) with mapi id 15.20.1273.030;\n\tThu, 1 Nov 2018 12:19:34 +0000"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com;\n\ts=selector1;\n\th=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;\n\tbh=SeN7I0DsEgkI13su8OfMdj8JqUr046kimLyVoDetMno=;\n\tb=UGvshRPlhZ05f9sSZ6iT2h0Bpn7uZELPkfykbSZAyjnYEdp18WPyK7hOm4rFsTDQS6wdbjxF6JpxIfxP0aAzLH9i9v1RuKVbGypoPmI59FyFGm9KmhsF3tX8DnuFkuDGLCLs1jOd0tPuWSsyK7UkJTW47gG6Rh0ajsF+fVJDU7Y=",
        "From": "Slava Ovsiienko <viacheslavo@mellanox.com>",
        "To": "Shahaf Shuler <shahafs@mellanox.com>",
        "CC": "\"dev@dpdk.org\" <dev@dpdk.org>, Yongseok Koh <yskoh@mellanox.com>, Slava\n\tOvsiienko <viacheslavo@mellanox.com>",
        "Thread-Topic": "[PATCH v3 12/13] net/mlx5: add e-switch VXLAN encapsulation\n\trules",
        "Thread-Index": "AQHUcd0mrZZu4L44ykqiEclpCggDHQ==",
        "Date": "Thu, 1 Nov 2018 12:19:34 +0000",
        "Message-ID": "<1541074741-41368-13-git-send-email-viacheslavo@mellanox.com>",
        "References": "<1539612815-47199-1-git-send-email-viacheslavo@mellanox.com>\n\t<1541074741-41368-1-git-send-email-viacheslavo@mellanox.com>",
        "In-Reply-To": "<1541074741-41368-1-git-send-email-viacheslavo@mellanox.com>",
        "Accept-Language": "en-US",
        "Content-Language": "en-US",
        "X-MS-Has-Attach": "",
        "X-MS-TNEF-Correlator": "",
        "x-clientproxiedby": "LO2P265CA0079.GBRP265.PROD.OUTLOOK.COM\n\t(2603:10a6:600:8::19) To AM4PR05MB3265.eurprd05.prod.outlook.com\n\t(2603:10a6:205:4::22)",
        "authentication-results": "spf=none (sender IP is )\n\tsmtp.mailfrom=viacheslavo@mellanox.com; ",
        "x-ms-exchange-messagesentrepresentingtype": "1",
        "x-originating-ip": "[37.142.13.130]",
        "x-ms-publictraffictype": "Email",
        "x-microsoft-exchange-diagnostics": "1; AM4PR05MB1457;\n\t6:otIYb9ZwGxc4aQwTe+nYuYu+Ov+qRwnsICZrXfIzLnSUbwOTW0lqrSAo3NigZk7IbXkjlacMo+/9aeP7N4K6C+N2Abmt1PPvYkt4O1YeFr9LeBzW7xrVf95+CMcF7oxMA6Jrvte7vzCsGCq8h5Cn1sVlQGzsgvx6s/h3q3MDzEP5U3aWLShxJMV+zaYbrrRvBLfBTKteeFVxLwneG20YBM5i8bQY6DD2B6IOl21zSE1iLZl6UraqE3wrTi9FaUb1PqgTv0RFZqmMn6hbllW3GStTuokC+O/3CzaFsEEAVF/zZaQYyK7fV5gRPDqnktujBMLv3luqc761he7ytKQ/ewDH2mcSCNxgbwjdEAoZnDBc+NjtKLWlvUS5dS2Nr2ql8n3def/a5o4rDUeA93jS0HJKfC5ydhwUCXtRIpGUJUXoS952BHk86AAUdU9v08BFSvcp7q6Gc4LvWL91MQY6aQ==;\n\t5:Eio2dVQe0BOUhNkQ5wbvzfBw22WLTKoD6kR6RAyJC1DoimV6Z+37PxmaU7c7PCY1/aZdET7zR+rd44+a+mMqhiHc6GNJeeVu11MO8FKyNXdSzHQWtsLumBT3FfDn0cQfy5ez41Ac3S2hb0Fz6WVEM2Js9bp22LZMI97fe2R65zU=;\n\t7:SDQju1/fMdw1RL93h0v7pssVHfFZBCAPgtkGMnUnwP06sW3odY+oBoTTc2qRNOICIpLBx/E6WJTblW3swUAclqVjBS0qZo/RR70MWyCpgpIhRjATz8ebqY4LchzNfQGnWbnHhNpKs/tphMPvbjKlsA==",
        "x-ms-office365-filtering-correlation-id": "0f56e435-f928-43da-b71f-08d63ff44885",
        "x-ms-office365-filtering-ht": "Tenant",
        "x-microsoft-antispam": "BCL:0; PCL:0;\n\tRULEID:(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020);\n\tSRVR:AM4PR05MB1457; ",
        "x-ms-traffictypediagnostic": "AM4PR05MB1457:",
        "x-microsoft-antispam-prvs": "<AM4PR05MB1457BD429D8A63B9B2B20C27D2CE0@AM4PR05MB1457.eurprd05.prod.outlook.com>",
        "x-exchange-antispam-report-test": "UriScan:(211171220733660);",
        "x-ms-exchange-senderadcheck": "1",
        "x-exchange-antispam-report-cfa-test": "BCL:0; PCL:0;\n\tRULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(3231382)(944501410)(52105095)(93006095)(93001095)(10201501046)(3002001)(6055026)(148016)(149066)(150057)(6041310)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(201708071742011)(7699051)(76991095);\n\tSRVR:AM4PR05MB1457; BCL:0; PCL:0; RULEID:; SRVR:AM4PR05MB1457; ",
        "x-forefront-prvs": "0843C17679",
        "x-forefront-antispam-report": "SFV:NSPM;\n\tSFS:(10009020)(376002)(396003)(39860400002)(346002)(136003)(366004)(199004)(189003)(11346002)(446003)(106356001)(476003)(105586002)(4326008)(97736004)(2616005)(478600001)(6636002)(5250100002)(99286004)(486006)(66066001)(6862004)(2900100001)(25786009)(37006003)(54906003)(5660300001)(316002)(8936002)(8676002)(81156014)(81166006)(4744004)(68736007)(7736002)(305945005)(3846002)(6116002)(76176011)(2906002)(102836004)(26005)(186003)(386003)(6506007)(107886003)(14454004)(6486002)(52116002)(6512007)(53936002)(6436002)(36756003)(86362001)(71190400001)(71200400001)(14444005)(5024004)(256004);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR05MB1457;\n\tH:AM4PR05MB3265.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en;\n\tPTR:InfoNoRecords; A:1; MX:1; ",
        "received-spf": "None (protection.outlook.com: mellanox.com does not designate\n\tpermitted sender hosts)",
        "x-microsoft-antispam-message-info": "9rpoNj16KPzO5DqVRUT6HIFqxn9mJvNY8rMIHNpm3R6GMUs2kxjFcczLfsjBDfK1PhMIrIhLxI077xGHvlzIl/UXwr9Z88WOhQmk4EI8O/G4zIwFKWrA3z77cL5vBmC9DqjjzUrnlkM7Zoznqs6Y//ZvmL8rEWCfR4vcjknpSv1L8yY2TSbcFUBEynvcddmcK9V1HjgfvH57OARZ81RT1pIGLsdPH24UporczskJVAi26atSUOo/eMyhWabD98ndZ8ZBJHad21q1zZPJP0kJJU+NDp9LYKsJNvwZSFqxfkpz7XjwOWeYoUSuYGu94JXkO7nUwTo2rUEV6ycoUxHayZURp+GSq1KlmdqpezVN5+g=",
        "spamdiagnosticoutput": "1:99",
        "spamdiagnosticmetadata": "NSPM",
        "Content-Type": "text/plain; charset=\"iso-8859-1\"",
        "Content-Transfer-Encoding": "quoted-printable",
        "MIME-Version": "1.0",
        "X-OriginatorOrg": "Mellanox.com",
        "X-MS-Exchange-CrossTenant-Network-Message-Id": "0f56e435-f928-43da-b71f-08d63ff44885",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "01 Nov 2018 12:19:34.4702\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-fromentityheader": "Hosted",
        "X-MS-Exchange-CrossTenant-id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM4PR05MB1457",
        "Subject": "[dpdk-dev] [PATCH v3 12/13] net/mlx5: add e-switch VXLAN\n\tencapsulation rules",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n\t<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\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "VXLAN encap rules are applied to the VF ingress traffic and have the\nVTEP as actual redirection destinations instead of outer PF.\nThe encapsulation rule should provide:\n- redirection action VF->PF\n- VF port ID\n- some inner network parameters (MACs/IP)\n- the tunnel outer source IP (v4/v6)\n- the tunnel outer destination IP (v4/v6). Current\n- VNI - Virtual Network Identifier\n\nThere is no direct way found to provide kernel with all required\nencapsulatioh header parameters. The encapsulation VTEP is created\nattached to the outer interface and assumed as default path for\negress encapsulated traffic. The outer tunnel IP address are\nassigned to interface using Netlink, the implicit route is\ncreated like this:\n\n  ip addr add <src_ip> peer <dst_ip> dev <outer> scope link\n\nPeer address provides implicit route, and scode link reduces\nthe risk of conflicts. At initialization time all local scope\nlink addresses are flushed from device (see next part of patchset).\n\nThe destination MAC address is provided via permenent neigh rule:\n\n  ip neigh add dev <outer> lladdr <dst_mac> to <dst_ip> nud permanent\n\nAt initialization time all neigh rules of this type are flushed\nfrom device (see the next part of patchset).\n\nSuggested-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>\nSigned-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>\n---\n drivers/net/mlx5/mlx5_flow_tcf.c | 386 +++++++++++++++++++++++++++++++++++++++\n 1 file changed, 386 insertions(+)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c\nindex c6e07f5..eae80ae 100644\n--- a/drivers/net/mlx5/mlx5_flow_tcf.c\n+++ b/drivers/net/mlx5/mlx5_flow_tcf.c\n@@ -3756,6 +3756,374 @@ struct pedit_parser {\n #define MNL_REQUEST_SIZE RTE_MIN(RTE_MAX(sysconf(_SC_PAGESIZE), \\\n \t\t\t\t MNL_REQUEST_SIZE_MIN), MNL_REQUEST_SIZE_MAX)\n \n+/**\n+ * Emit Netlink message to add/remove local address to the outer device.\n+ * The address being added is visible within the link only (scope link).\n+ *\n+ * Note that an implicit route is maintained by the kernel due to the\n+ * presence of a peer address (IFA_ADDRESS).\n+ *\n+ * These rules are used for encapsultion only and allow to assign\n+ * the outer tunnel source IP address.\n+ *\n+ * @param[in] tcf\n+ *   Libmnl socket context object.\n+ * @param[in] encap\n+ *   Encapsulation properties (source address and its peer).\n+ * @param[in] ifindex\n+ *   Network interface to apply rule.\n+ * @param[in] enable\n+ *   Toggle between add and remove.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+flow_tcf_rule_local(struct mlx5_flow_tcf_context *tcf,\n+\t\t    const struct flow_tcf_vxlan_encap *encap,\n+\t\t    unsigned int ifindex,\n+\t\t    bool enable,\n+\t\t    struct rte_flow_error *error)\n+{\n+\tstruct nlmsghdr *nlh;\n+\tstruct ifaddrmsg *ifa;\n+\talignas(struct nlmsghdr)\n+\tuint8_t buf[mnl_nlmsg_size(sizeof(*ifa) + 128)];\n+\n+\tnlh = mnl_nlmsg_put_header(buf);\n+\tnlh->nlmsg_type = enable ? RTM_NEWADDR : RTM_DELADDR;\n+\tnlh->nlmsg_flags =\n+\t\tNLM_F_REQUEST | (enable ? NLM_F_CREATE | NLM_F_REPLACE : 0);\n+\tnlh->nlmsg_seq = 0;\n+\tifa = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifa));\n+\tifa->ifa_flags = IFA_F_PERMANENT;\n+\tifa->ifa_scope = RT_SCOPE_LINK;\n+\tifa->ifa_index = ifindex;\n+\tif (encap->mask & FLOW_TCF_ENCAP_IPV4_SRC) {\n+\t\tifa->ifa_family = AF_INET;\n+\t\tifa->ifa_prefixlen = 32;\n+\t\tmnl_attr_put_u32(nlh, IFA_LOCAL, encap->ipv4.src);\n+\t\tif (encap->mask & FLOW_TCF_ENCAP_IPV4_DST)\n+\t\t\tmnl_attr_put_u32(nlh, IFA_ADDRESS,\n+\t\t\t\t\t      encap->ipv4.dst);\n+\t} else {\n+\t\tassert(encap->mask & FLOW_TCF_ENCAP_IPV6_SRC);\n+\t\tifa->ifa_family = AF_INET6;\n+\t\tifa->ifa_prefixlen = 128;\n+\t\tmnl_attr_put(nlh, IFA_LOCAL,\n+\t\t\t\t  sizeof(encap->ipv6.src),\n+\t\t\t\t  &encap->ipv6.src);\n+\t\tif (encap->mask & FLOW_TCF_ENCAP_IPV6_DST)\n+\t\t\tmnl_attr_put(nlh, IFA_ADDRESS,\n+\t\t\t\t\t  sizeof(encap->ipv6.dst),\n+\t\t\t\t\t  &encap->ipv6.dst);\n+\t}\n+\tif (!flow_tcf_nl_ack(tcf, nlh, 0, NULL, NULL))\n+\t\treturn 0;\n+\treturn rte_flow_error_set\n+\t\t(error, rte_errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t \"netlink: cannot complete IFA request (ip addr add)\");\n+}\n+\n+/**\n+ * Emit Netlink message to add/remove neighbor.\n+ *\n+ * @param[in] tcf\n+ *   Libmnl socket context object.\n+ * @param[in] encap\n+ *   Encapsulation properties (destination address).\n+ * @param[in] ifindex\n+ *   Network interface.\n+ * @param[in] enable\n+ *   Toggle between add and remove.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+flow_tcf_rule_neigh(struct mlx5_flow_tcf_context *tcf,\n+\t\t     const struct flow_tcf_vxlan_encap *encap,\n+\t\t     unsigned int ifindex,\n+\t\t     bool enable,\n+\t\t     struct rte_flow_error *error)\n+{\n+\tstruct nlmsghdr *nlh;\n+\tstruct ndmsg *ndm;\n+\talignas(struct nlmsghdr)\n+\tuint8_t buf[mnl_nlmsg_size(sizeof(*ndm) + 128)];\n+\n+\tnlh = mnl_nlmsg_put_header(buf);\n+\tnlh->nlmsg_type = enable ? RTM_NEWNEIGH : RTM_DELNEIGH;\n+\tnlh->nlmsg_flags =\n+\t\tNLM_F_REQUEST | (enable ? NLM_F_CREATE | NLM_F_REPLACE : 0);\n+\tnlh->nlmsg_seq = 0;\n+\tndm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ndm));\n+\tndm->ndm_ifindex = ifindex;\n+\tndm->ndm_state = NUD_PERMANENT;\n+\tndm->ndm_flags = 0;\n+\tndm->ndm_type = 0;\n+\tif (encap->mask & FLOW_TCF_ENCAP_IPV4_DST) {\n+\t\tndm->ndm_family = AF_INET;\n+\t\tmnl_attr_put_u32(nlh, NDA_DST, encap->ipv4.dst);\n+\t} else {\n+\t\tassert(encap->mask & FLOW_TCF_ENCAP_IPV6_DST);\n+\t\tndm->ndm_family = AF_INET6;\n+\t\tmnl_attr_put(nlh, NDA_DST, sizeof(encap->ipv6.dst),\n+\t\t\t\t\t\t &encap->ipv6.dst);\n+\t}\n+\tif (encap->mask & FLOW_TCF_ENCAP_ETH_SRC && enable)\n+\t\tDRV_LOG(WARNING,\n+\t\t\t\"Outer ethernet source address cannot be \"\n+\t\t\t\"forced for VXLAN encapsulation\");\n+\tif (encap->mask & FLOW_TCF_ENCAP_ETH_DST)\n+\t\tmnl_attr_put(nlh, NDA_LLADDR, sizeof(encap->eth.dst),\n+\t\t\t\t\t\t    &encap->eth.dst);\n+\tif (!flow_tcf_nl_ack(tcf, nlh, 0, NULL, NULL))\n+\t\treturn 0;\n+\treturn rte_flow_error_set\n+\t\t(error, rte_errno, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t \"netlink: cannot complete ND request (ip neigh)\");\n+}\n+\n+/**\n+ * Manage the local IP addresses and their peers IP addresses on the\n+ * outer interface for encapsulation purposes. The kernel searches the\n+ * appropriate device for tunnel egress traffic using the outer source\n+ * IP, this IP should be assigned to the outer network device, otherwise\n+ * kernel rejects the rule.\n+ *\n+ * Adds or removes the addresses using the Netlink command like this:\n+ *   ip addr add <src_ip> peer <dst_ip> scope link dev <ifouter>\n+ *\n+ * The addresses are local to the netdev (\"scope link\"), this reduces\n+ * the risk of conflicts. Note that an implicit route is maintained by\n+ * the kernel due to the presence of a peer address (IFA_ADDRESS).\n+ *\n+ * @param[in] tcf\n+ *   Libmnl socket context object.\n+ * @param[in] vtep\n+ *   VTEP object, contains rule database and ifouter index.\n+ * @param[in] dev_flow\n+ *   Flow object, contains the tunnel parameters (for encap only).\n+ * @param[in] enable\n+ *   Toggle between add and remove.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+flow_tcf_encap_local(struct mlx5_flow_tcf_context *tcf,\n+\t\t     struct tcf_vtep *vtep,\n+\t\t     struct mlx5_flow *dev_flow,\n+\t\t     bool enable,\n+\t\t     struct rte_flow_error *error)\n+{\n+\tconst struct flow_tcf_vxlan_encap *encap = dev_flow->tcf.vxlan_encap;\n+\tstruct tcf_local_rule *rule;\n+\tbool found = false;\n+\tint ret;\n+\n+\tassert(encap);\n+\tassert(encap->hdr.type == FLOW_TCF_TUNACT_VXLAN_ENCAP);\n+\tif (encap->mask & FLOW_TCF_ENCAP_IPV4_SRC) {\n+\t\tassert(encap->mask & FLOW_TCF_ENCAP_IPV4_DST);\n+\t\tLIST_FOREACH(rule, &vtep->local, next) {\n+\t\t\tif (rule->mask & FLOW_TCF_ENCAP_IPV4_SRC &&\n+\t\t\t    encap->ipv4.src == rule->ipv4.src &&\n+\t\t\t    encap->ipv4.dst == rule->ipv4.dst) {\n+\t\t\t\tfound = true;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t} else {\n+\t\tassert(encap->mask & FLOW_TCF_ENCAP_IPV6_SRC);\n+\t\tassert(encap->mask & FLOW_TCF_ENCAP_IPV6_DST);\n+\t\tLIST_FOREACH(rule, &vtep->local, next) {\n+\t\t\tif (rule->mask & FLOW_TCF_ENCAP_IPV6_SRC &&\n+\t\t\t    !memcmp(&encap->ipv6.src, &rule->ipv6.src,\n+\t\t\t\t\t    sizeof(encap->ipv6.src)) &&\n+\t\t\t    !memcmp(&encap->ipv6.dst, &rule->ipv6.dst,\n+\t\t\t\t\t    sizeof(encap->ipv6.dst))) {\n+\t\t\t\tfound = true;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\tif (found) {\n+\t\tif (enable) {\n+\t\t\trule->refcnt++;\n+\t\t\treturn 0;\n+\t\t}\n+\t\tif (!rule->refcnt || !--rule->refcnt) {\n+\t\t\tLIST_REMOVE(rule, next);\n+\t\t\treturn flow_tcf_rule_local(tcf, encap,\n+\t\t\t\t\tvtep->ifouter, false, error);\n+\t\t}\n+\t\treturn 0;\n+\t}\n+\tif (!enable) {\n+\t\tDRV_LOG(WARNING, \"Disabling not existing local rule\");\n+\t\trte_flow_error_set\n+\t\t\t(error, ENOENT, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t NULL, \"Disabling not existing local rule\");\n+\t\treturn -ENOENT;\n+\t}\n+\trule = rte_zmalloc(__func__, sizeof(struct tcf_local_rule),\n+\t\t\t\talignof(struct tcf_local_rule));\n+\tif (!rule) {\n+\t\trte_flow_error_set\n+\t\t\t(error, ENOMEM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t NULL, \"unable to allocate memory for local rule\");\n+\t\treturn -rte_errno;\n+\t}\n+\t*rule = (struct tcf_local_rule){.refcnt = 0,\n+\t\t\t\t\t.mask = 0,\n+\t\t\t\t\t};\n+\tif (encap->mask & FLOW_TCF_ENCAP_IPV4_SRC) {\n+\t\trule->mask = FLOW_TCF_ENCAP_IPV4_SRC\n+\t\t\t   | FLOW_TCF_ENCAP_IPV4_DST;\n+\t\trule->ipv4.src = encap->ipv4.src;\n+\t\trule->ipv4.dst = encap->ipv4.dst;\n+\t} else {\n+\t\trule->mask = FLOW_TCF_ENCAP_IPV6_SRC\n+\t\t\t   | FLOW_TCF_ENCAP_IPV6_DST;\n+\t\tmemcpy(&rule->ipv6.src, &encap->ipv6.src,\n+\t\t\t\tsizeof(rule->ipv6.src));\n+\t\tmemcpy(&rule->ipv6.dst, &encap->ipv6.dst,\n+\t\t\t\tsizeof(rule->ipv6.dst));\n+\t}\n+\tret = flow_tcf_rule_local(tcf, encap, vtep->ifouter, true, error);\n+\tif (ret) {\n+\t\trte_free(rule);\n+\t\treturn ret;\n+\t}\n+\trule->refcnt++;\n+\tLIST_INSERT_HEAD(&vtep->local, rule, next);\n+\treturn 0;\n+}\n+\n+/**\n+ * Manage the destination MAC/IP addresses neigh database, kernel uses\n+ * this one to determine the destination MAC address within encapsulation\n+ * header. Adds or removes the entries using the Netlink command like this:\n+ *   ip neigh add dev <ifouter> lladdr <dst_mac> to <dst_ip> nud permanent\n+ *\n+ * @param[in] tcf\n+ *   Libmnl socket context object.\n+ * @param[in] vtep\n+ *   VTEP object, contains rule database and ifouter index.\n+ * @param[in] dev_flow\n+ *   Flow object, contains the tunnel parameters (for encap only).\n+ * @param[in] enable\n+ *   Toggle between add and remove.\n+ * @param[out] error\n+ *   Perform verbose error reporting if not NULL.\n+ *\n+ * @return\n+ *   0 on success, a negative errno value otherwise and rte_errno is set.\n+ */\n+static int\n+flow_tcf_encap_neigh(struct mlx5_flow_tcf_context *tcf,\n+\t\t     struct tcf_vtep *vtep,\n+\t\t     struct mlx5_flow *dev_flow,\n+\t\t     bool enable,\n+\t\t     struct rte_flow_error *error)\n+{\n+\tconst struct flow_tcf_vxlan_encap *encap = dev_flow->tcf.vxlan_encap;\n+\tstruct tcf_neigh_rule *rule;\n+\tbool found = false;\n+\tint ret;\n+\n+\tassert(encap);\n+\tassert(encap->hdr.type == FLOW_TCF_TUNACT_VXLAN_ENCAP);\n+\tif (encap->mask & FLOW_TCF_ENCAP_IPV4_DST) {\n+\t\tassert(encap->mask & FLOW_TCF_ENCAP_IPV4_SRC);\n+\t\tLIST_FOREACH(rule, &vtep->neigh, next) {\n+\t\t\tif (rule->mask & FLOW_TCF_ENCAP_IPV4_DST &&\n+\t\t\t    encap->ipv4.dst == rule->ipv4.dst) {\n+\t\t\t\tfound = true;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t} else {\n+\t\tassert(encap->mask & FLOW_TCF_ENCAP_IPV6_SRC);\n+\t\tassert(encap->mask & FLOW_TCF_ENCAP_IPV6_DST);\n+\t\tLIST_FOREACH(rule, &vtep->neigh, next) {\n+\t\t\tif (rule->mask & FLOW_TCF_ENCAP_IPV6_DST &&\n+\t\t\t    !memcmp(&encap->ipv6.dst, &rule->ipv6.dst,\n+\t\t\t\t\t\tsizeof(encap->ipv6.dst))) {\n+\t\t\t\tfound = true;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\tif (found) {\n+\t\tif (memcmp(&encap->eth.dst, &rule->eth,\n+\t\t\t   sizeof(encap->eth.dst))) {\n+\t\t\tDRV_LOG(WARNING, \"Destination MAC differs\"\n+\t\t\t\t\t \" in neigh rule\");\n+\t\t\trte_flow_error_set(error, EEXIST,\n+\t\t\t\t\t   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t\t\t   NULL, \"Different MAC address\"\n+\t\t\t\t\t   \" neigh rule for the same\"\n+\t\t\t\t\t   \" destination IP\");\n+\t\t\t\t\treturn -EEXIST;\n+\t\t}\n+\t\tif (enable) {\n+\t\t\trule->refcnt++;\n+\t\t\treturn 0;\n+\t\t}\n+\t\tif (!rule->refcnt || !--rule->refcnt) {\n+\t\t\tLIST_REMOVE(rule, next);\n+\t\t\treturn flow_tcf_rule_neigh(tcf, encap,\n+\t\t\t\t\t\t   vtep->ifouter,\n+\t\t\t\t\t\t   false, error);\n+\t\t}\n+\t\treturn 0;\n+\t}\n+\tif (!enable) {\n+\t\tDRV_LOG(WARNING, \"Disabling not existing neigh rule\");\n+\t\trte_flow_error_set\n+\t\t\t(error, ENOENT, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t NULL, \"unable to allocate memory for neigh rule\");\n+\t\treturn -ENOENT;\n+\t}\n+\trule = rte_zmalloc(__func__, sizeof(struct tcf_neigh_rule),\n+\t\t\t\talignof(struct tcf_neigh_rule));\n+\tif (!rule) {\n+\t\trte_flow_error_set\n+\t\t\t(error, ENOMEM, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,\n+\t\t\t NULL, \"unadble to allocate memory for neigh rule\");\n+\t\treturn -rte_errno;\n+\t}\n+\t*rule = (struct tcf_neigh_rule){.refcnt = 0,\n+\t\t\t\t\t.mask = 0,\n+\t\t\t\t\t};\n+\tif (encap->mask & FLOW_TCF_ENCAP_IPV4_DST) {\n+\t\trule->mask = FLOW_TCF_ENCAP_IPV4_DST;\n+\t\trule->ipv4.dst = encap->ipv4.dst;\n+\t} else {\n+\t\trule->mask = FLOW_TCF_ENCAP_IPV6_DST;\n+\t\tmemcpy(&rule->ipv6.dst, &encap->ipv6.dst,\n+\t\t\t\t\tsizeof(rule->ipv6.dst));\n+\t}\n+\tmemcpy(&rule->eth, &encap->eth.dst, sizeof(rule->eth));\n+\tret = flow_tcf_rule_neigh(tcf, encap, vtep->ifouter, true, error);\n+\tif (ret) {\n+\t\trte_free(rule);\n+\t\treturn ret;\n+\t}\n+\trule->refcnt++;\n+\tLIST_INSERT_HEAD(&vtep->neigh, rule, next);\n+\treturn 0;\n+}\n+\n /* VTEP device list is shared between PMD port instances. */\n static LIST_HEAD(, tcf_vtep) vtep_list_vxlan = LIST_HEAD_INITIALIZER();\n static pthread_mutex_t vtep_list_mutex = PTHREAD_MUTEX_INITIALIZER;\n@@ -4032,6 +4400,7 @@ struct pedit_parser {\n {\n \tstatic uint16_t encap_port = MLX5_VXLAN_PORT_MIN - 1;\n \tstruct tcf_vtep *vtep;\n+\tint ret;\n \n \tassert(ifouter);\n \t/* Look whether the attached VTEP for encap is created. */\n@@ -4077,6 +4446,20 @@ struct pedit_parser {\n \t}\n \tassert(vtep->ifouter == ifouter);\n \tassert(vtep->ifindex);\n+\t/* Create local ipaddr with peer to specify the outer IPs. */\n+\tret = flow_tcf_encap_local(tcf, vtep, dev_flow, true, error);\n+\tif (!ret) {\n+\t\t/* Create neigh rule to specify outer destination MAC. */\n+\t\tret = flow_tcf_encap_neigh(tcf, vtep, dev_flow, true, error);\n+\t\tif (ret)\n+\t\t\tflow_tcf_encap_local(tcf, vtep,\n+\t\t\t\t\t     dev_flow, false, error);\n+\t}\n+\tif (ret) {\n+\t\tif (--vtep->refcnt == 0)\n+\t\t\tflow_tcf_vtep_delete(tcf, vtep);\n+\t\treturn NULL;\n+\t}\n \treturn vtep;\n }\n \n@@ -4146,6 +4529,9 @@ struct pedit_parser {\n \tcase FLOW_TCF_TUNACT_VXLAN_DECAP:\n \t\tbreak;\n \tcase FLOW_TCF_TUNACT_VXLAN_ENCAP:\n+\t\t/* Remove the encap ancillary rules first. */\n+\t\tflow_tcf_encap_neigh(tcf, vtep, dev_flow, false, NULL);\n+\t\tflow_tcf_encap_local(tcf, vtep, dev_flow, false, NULL);\n \t\tbreak;\n \tdefault:\n \t\tassert(false);\n",
    "prefixes": [
        "v3",
        "12/13"
    ]
}