get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 45801,
    "url": "http://patchwork.dpdk.org/api/patches/45801/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/1538461807-37507-2-git-send-email-viacheslavo@mellanox.com/",
    "project": {
        "id": 1,
        "url": "http://patchwork.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": "<1538461807-37507-2-git-send-email-viacheslavo@mellanox.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1538461807-37507-2-git-send-email-viacheslavo@mellanox.com",
    "date": "2018-10-02T06:30:36",
    "name": "[2/5] net/mlx5: e-switch VXLAN netlink routines update",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "351f7a12be4ef971afa00b1f8c8430d8a20c4d4b",
    "submitter": {
        "id": 1102,
        "url": "http://patchwork.dpdk.org/api/people/1102/?format=api",
        "name": "Slava Ovsiienko",
        "email": "viacheslavo@mellanox.com"
    },
    "delegate": {
        "id": 6624,
        "url": "http://patchwork.dpdk.org/api/users/6624/?format=api",
        "username": "shahafs",
        "first_name": "Shahaf",
        "last_name": "Shuler",
        "email": "shahafs@mellanox.com"
    },
    "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/1538461807-37507-2-git-send-email-viacheslavo@mellanox.com/mbox/",
    "series": [
        {
            "id": 1626,
            "url": "http://patchwork.dpdk.org/api/series/1626/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=1626",
            "date": "2018-10-02T06:30:36",
            "name": null,
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/1626/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/45801/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/45801/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 A4C9D4C99;\n\tTue,  2 Oct 2018 08:30:39 +0200 (CEST)",
            "from EUR01-DB5-obe.outbound.protection.outlook.com\n\t(mail-db5eur01on0064.outbound.protection.outlook.com [104.47.2.64])\n\tby dpdk.org (Postfix) with ESMTP id F073744BE\n\tfor <dev@dpdk.org>; Tue,  2 Oct 2018 08:30:37 +0200 (CEST)",
            "from AM4PR05MB3265.eurprd05.prod.outlook.com (10.171.186.150) by\n\tAM4PR05MB3443.eurprd05.prod.outlook.com (10.171.187.148) with\n\tMicrosoft SMTP Server (version=TLS1_2,\n\tcipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id\n\t15.20.1185.25; Tue, 2 Oct 2018 06:30:36 +0000",
            "from AM4PR05MB3265.eurprd05.prod.outlook.com\n\t([fe80::81a1:b719:2345:50e5]) by\n\tAM4PR05MB3265.eurprd05.prod.outlook.com\n\t([fe80::81a1:b719:2345:50e5%5]) with mapi id 15.20.1185.024;\n\tTue, 2 Oct 2018 06:30:36 +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=o2LRQqt4xmlG9ZvbLLyVMGuUx6zB0cahN+jYzdeTPq0=;\n\tb=InFJ1lcSpSnAw09RpH+2kbgM5MmUh9y9GtuB3zkzh2TtRMeIIawmS2pgrzrvK5AN/pnibTP0hbo4xzj2QO/FPurgYkGuTDlTNxvNUuzRpuOy1rj6K70NHxxVjvQ6OSh4zEcdQ7Qaq1QX8Xg0jGIDy2Jj11/THIrtHWZdYDdtQ0M=",
        "From": "Slava Ovsiienko <viacheslavo@mellanox.com>",
        "To": "\"dev@dpdk.org\" <dev@dpdk.org>",
        "CC": "Shahaf Shuler <shahafs@mellanox.com>, Slava Ovsiienko\n\t<viacheslavo@mellanox.com>",
        "Thread-Topic": "[PATCH 2/5] net/mlx5: e-switch VXLAN netlink routines update",
        "Thread-Index": "AQHUWhltm+DQLIgIZUK7lo+WLLLXLw==",
        "Date": "Tue, 2 Oct 2018 06:30:36 +0000",
        "Message-ID": "<1538461807-37507-2-git-send-email-viacheslavo@mellanox.com>",
        "References": "<1538461807-37507-1-git-send-email-viacheslavo@mellanox.com>",
        "In-Reply-To": "<1538461807-37507-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": "AM0PR02CA0019.eurprd02.prod.outlook.com\n\t(2603:10a6:208:3e::32) 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; AM4PR05MB3443;\n\t6:3YfMn9GB2b4EnpV96VEGsjHqSadDJObU6K6CU3CovXXMgk3q4f/4lVVc3u48RtAdutkNL8it5jJEgP9fa2fFaa6oLu6oYgSz2O4bHdautf9pUSLIMTmTyWGFiyEE1T3/sbri/85zXQe0LYjLQj7rvOfnR5tl1xFgcsIh18QoVB5kdQr2GS6jGHW5Gxzh62slAuzjGrQUcxEN6WlxgQD3evy8SPH980Ik4ZbJZnegyHAcgC4pPXPp1UUK+dbcUTmsiaMDQORm6IsRAfaeAHED6rV3B1yZ8Kc4M6bNoT+A11RpS3ISMmw49+AJsi+oTZB7zvjvBptKzuJhZHlmTEhT54ZUhQsZPqx5GyU1oabRgL7Xjx0HxwB3/TCu7cZjc+ZuzRfVVKp3+fishaUPVw2PP6NScQd7+CFoHNCEcA6IUihT7NDqtqcck6US9FKgk9ynZIZhnzzf+0+2J8oYcjY8DA==;\n\t5:ib2vGdqNJChVkdJF4R4dF+wqlEy4LgkqRLlnMq9lhaNV2UovE0a8fIHP6PDQEIvwDtNHIew/8QK6BenkX9gLMdJwdL2VonnJk0fjppbUNA9pWxMRaWWnP3hPaLyarvluwOciFwRNH3+SnWBTvEfK7QlNxiyo+t254FL+Jh5B3jQ=;\n\t7:no4kJHKPH8UB4wBPDWhCPwSNloT068dxIA1cPUVHsifEkhvPIgsBexad1xsyMIBp3bta0GjY8W1jC2DlW/dbahkNxI3NV2+1EW7Pu225kWe7jaX4F1aZHKruniojb3B/1LqJHottPmC2peJMyEP4FYO+gp8ORW9nXfbFd6lPepK18Pu7tqeTFIUAUMc22p3HxhYZAZgec7b9fEt1fefPi7SCVm3AgTiA9YLMuNQypv1x/ogGWDKq2DYG08lvkcqq",
        "x-ms-office365-filtering-correlation-id": "36653fcd-a60b-4c53-3a22-08d62830904b",
        "x-ms-office365-filtering-ht": "Tenant",
        "x-microsoft-antispam": "BCL:0; PCL:0;\n\tRULEID:(7020095)(4652040)(8989299)(4534165)(4627221)(201703031133081)(201702281549075)(8990200)(5600074)(711020)(4618075)(2017052603328)(7153060)(7193020);\n\tSRVR:AM4PR05MB3443; ",
        "x-ms-traffictypediagnostic": "AM4PR05MB3443:",
        "x-microsoft-antispam-prvs": "<AM4PR05MB344365D1700B0745331E9548D2E80@AM4PR05MB3443.eurprd05.prod.outlook.com>",
        "x-exchange-antispam-report-test": "UriScan:(269456686620040)(211171220733660); ",
        "x-ms-exchange-senderadcheck": "1",
        "x-exchange-antispam-report-cfa-test": "BCL:0; PCL:0;\n\tRULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3231355)(944501410)(52105095)(3002001)(10201501046)(93006095)(93001095)(6055026)(149066)(150057)(6041310)(20161123560045)(20161123558120)(20161123562045)(20161123564045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(201708071742011)(7699051);\n\tSRVR:AM4PR05MB3443; BCL:0; PCL:0; RULEID:; SRVR:AM4PR05MB3443; ",
        "x-forefront-prvs": "0813C68E65",
        "x-forefront-antispam-report": "SFV:NSPM;\n\tSFS:(10009020)(396003)(136003)(39860400002)(376002)(366004)(346002)(189003)(199004)(5024004)(5640700003)(256004)(25786009)(14444005)(26005)(106356001)(54906003)(186003)(316002)(102836004)(68736007)(105586002)(6116002)(3846002)(97736004)(14454004)(81156014)(1730700003)(86362001)(2351001)(2900100001)(8676002)(575784001)(7736002)(2616005)(8936002)(476003)(305945005)(446003)(11346002)(81166006)(6486002)(52116002)(386003)(6436002)(6506007)(15650500001)(53936002)(2906002)(4326008)(71200400001)(36756003)(478600001)(486006)(99286004)(5250100002)(66066001)(76176011)(5660300001)(6512007)(2501003)(6916009)(4744004)(71190400001)(107886003);\n\tDIR:OUT; SFP:1101; SCL:1; SRVR:AM4PR05MB3443;\n\tH:AM4PR05MB3265.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en;\n\tPTR:InfoNoRecords; MX:1; A:1; ",
        "received-spf": "None (protection.outlook.com: mellanox.com does not designate\n\tpermitted sender hosts)",
        "x-microsoft-antispam-message-info": "pwel+OyXD8PG5SoM8fM5ciRb9CzHG+qNWfYmDWJiTs/90w095Lu57lb2QHtF6BSqMHG+7TYa8g8tTYBf6reoArYYl0UVFsNuBM5CTVH0g6puMjONWgVnxjB/U6gkua5YD330JAqJ2Zpsq5h7DxHR8FzktSRSTlwghiH6Qzk7zRhi0bxJbQbRqCyMszqju6/0tRaI3vORdQdSY+GP64re2FBYTN1DTIjF0faovINTSN6xIiKJh/xtl9kAKvmMNi048k6Moc7qldtKNhanpz9InM+t2DQg+zngWf8/XKF5qy5WLFzDIhwwsYZ1d2gmbd1a1GvGkAXh71z5+c3DMJbQbnTVvm14eqzfK1Zuo2FpN9g=",
        "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": "36653fcd-a60b-4c53-3a22-08d62830904b",
        "X-MS-Exchange-CrossTenant-originalarrivaltime": "02 Oct 2018 06:30:36.7376\n\t(UTC)",
        "X-MS-Exchange-CrossTenant-fromentityheader": "Hosted",
        "X-MS-Exchange-CrossTenant-id": "a652971c-7d2e-4d9b-a6a4-d149256f461b",
        "X-MS-Exchange-Transport-CrossTenantHeadersStamped": "AM4PR05MB3443",
        "Subject": "[dpdk-dev] [PATCH 2/5] net/mlx5: e-switch VXLAN netlink routines\n\tupdate",
        "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": "This part of patchset updates Netlink exchange routines. Message sequence\nnumbers became not random ones, the multipart reply messages are supported,\nnot propagating errors to the following socket calls, Netlink replies\nbuffer size is increased to MNL_SOCKET_BUFFER_SIZE.\n\nSuggested-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>\nSigned-off-by: Viacheslav Ovsiienko <viacheslavo@mellanox.com>\n---\n drivers/net/mlx5/mlx5.c          |  18 ++--\n drivers/net/mlx5/mlx5.h          |   7 +-\n drivers/net/mlx5/mlx5_flow.h     |   9 +-\n drivers/net/mlx5/mlx5_flow_tcf.c | 214 +++++++++++++++++++++++----------------\n 4 files changed, 147 insertions(+), 101 deletions(-)",
    "diff": "diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c\nindex 4be6a1c..201a26e 100644\n--- a/drivers/net/mlx5/mlx5.c\n+++ b/drivers/net/mlx5/mlx5.c\n@@ -287,8 +287,7 @@\n \t\tclose(priv->nl_socket_route);\n \tif (priv->nl_socket_rdma >= 0)\n \t\tclose(priv->nl_socket_rdma);\n-\tif (priv->mnl_socket)\n-\t\tmlx5_flow_tcf_socket_destroy(priv->mnl_socket);\n+\tmlx5_flow_tcf_socket_close(&priv->tcf_socket);\n \tret = mlx5_hrxq_ibv_verify(dev);\n \tif (ret)\n \t\tDRV_LOG(WARNING, \"port %u some hash Rx queue still remain\",\n@@ -1138,8 +1137,9 @@\n \tclaim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0));\n \tif (vf && config.vf_nl_en)\n \t\tmlx5_nl_mac_addr_sync(eth_dev);\n-\tpriv->mnl_socket = mlx5_flow_tcf_socket_create();\n-\tif (!priv->mnl_socket) {\n+\t/* Initialize Netlink socket for e-switch control */\n+\terr = mlx5_flow_tcf_socket_open(&priv->tcf_socket);\n+\tif (err) {\n \t\terr = -rte_errno;\n \t\tDRV_LOG(WARNING,\n \t\t\t\"flow rules relying on switch offloads will not be\"\n@@ -1154,16 +1154,15 @@\n \t\t\terror.message =\n \t\t\t\t\"cannot retrieve network interface index\";\n \t\t} else {\n-\t\t\terr = mlx5_flow_tcf_init(priv->mnl_socket, ifindex,\n-\t\t\t\t\t\t&error);\n+\t\t\terr = mlx5_flow_tcf_ifindex_init(&priv->tcf_socket,\n+\t\t\t\t\t\t\t ifindex, &error);\n \t\t}\n \t\tif (err) {\n \t\t\tDRV_LOG(WARNING,\n \t\t\t\t\"flow rules relying on switch offloads will\"\n \t\t\t\t\" not be supported: %s: %s\",\n \t\t\t\terror.message, strerror(rte_errno));\n-\t\t\tmlx5_flow_tcf_socket_destroy(priv->mnl_socket);\n-\t\t\tpriv->mnl_socket = NULL;\n+\t\t\tmlx5_flow_tcf_socket_close(&priv->tcf_socket);\n \t\t}\n \t}\n \tTAILQ_INIT(&priv->flows);\n@@ -1218,8 +1217,7 @@\n \t\t\tclose(priv->nl_socket_route);\n \t\tif (priv->nl_socket_rdma >= 0)\n \t\t\tclose(priv->nl_socket_rdma);\n-\t\tif (priv->mnl_socket)\n-\t\t\tmlx5_flow_tcf_socket_destroy(priv->mnl_socket);\n+\t\tmlx5_flow_tcf_socket_close(&priv->tcf_socket);\n \t\tif (own_domain_id)\n \t\t\tclaim_zero(rte_eth_switch_domain_free(priv->domain_id));\n \t\trte_free(priv);\ndiff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h\nindex 8de0d74..b327a39 100644\n--- a/drivers/net/mlx5/mlx5.h\n+++ b/drivers/net/mlx5/mlx5.h\n@@ -160,6 +160,11 @@ struct mlx5_drop {\n \n struct mnl_socket;\n \n+struct mlx5_tcf_socket {\n+\tuint32_t seq; /* Message sequence number. */\n+\tstruct mnl_socket *nl; /* NETLINK_ROUTE libmnl socket. */\n+};\n+\n struct priv {\n \tLIST_ENTRY(priv) mem_event_cb; /* Called by memory event callback. */\n \tstruct rte_eth_dev_data *dev_data;  /* Pointer to device data. */\n@@ -220,12 +225,12 @@ struct priv {\n \tint nl_socket_rdma; /* Netlink socket (NETLINK_RDMA). */\n \tint nl_socket_route; /* Netlink socket (NETLINK_ROUTE). */\n \tuint32_t nl_sn; /* Netlink message sequence number. */\n+\tstruct mlx5_tcf_socket tcf_socket; /* Libmnl socket for tcf. */\n #ifndef RTE_ARCH_64\n \trte_spinlock_t uar_lock_cq; /* CQs share a common distinct UAR */\n \trte_spinlock_t uar_lock[MLX5_UAR_PAGE_NUM_MAX];\n \t/* UAR same-page access control required in 32bit implementations. */\n #endif\n-\tstruct mnl_socket *mnl_socket; /* Libmnl socket. */\n };\n \n #define PORT_ID(priv) ((priv)->dev_data->port_id)\ndiff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h\nindex 2d56ced..fff905a 100644\n--- a/drivers/net/mlx5/mlx5_flow.h\n+++ b/drivers/net/mlx5/mlx5_flow.h\n@@ -348,9 +348,10 @@ int mlx5_flow_validate_item_vxlan_gpe(const struct rte_flow_item *item,\n \n /* mlx5_flow_tcf.c */\n \n-int mlx5_flow_tcf_init(struct mnl_socket *nl, unsigned int ifindex,\n-\t\t       struct rte_flow_error *error);\n-struct mnl_socket *mlx5_flow_tcf_socket_create(void);\n-void mlx5_flow_tcf_socket_destroy(struct mnl_socket *nl);\n+int mlx5_flow_tcf_ifindex_init(struct mlx5_tcf_socket *tcf,\n+\t\t\t       unsigned int ifindex,\n+\t\t\t       struct rte_flow_error *error);\n+int mlx5_flow_tcf_socket_open(struct mlx5_tcf_socket *tcf);\n+void mlx5_flow_tcf_socket_close(struct mlx5_tcf_socket *tcf);\n \n #endif /* RTE_PMD_MLX5_FLOW_H_ */\ndiff --git a/drivers/net/mlx5/mlx5_flow_tcf.c b/drivers/net/mlx5/mlx5_flow_tcf.c\nindex 5c93412..15e250c 100644\n--- a/drivers/net/mlx5/mlx5_flow_tcf.c\n+++ b/drivers/net/mlx5/mlx5_flow_tcf.c\n@@ -1552,8 +1552,8 @@ struct flow_tcf_ptoi {\n /**\n  * Send Netlink message with acknowledgment.\n  *\n- * @param nl\n- *   Libmnl socket to use.\n+ * @param tcf\n+ *   Libmnl socket context to use.\n  * @param nlh\n  *   Message to send. This function always raises the NLM_F_ACK flag before\n  *   sending.\n@@ -1562,26 +1562,108 @@ struct flow_tcf_ptoi {\n  *   0 on success, a negative errno value otherwise and rte_errno is set.\n  */\n static int\n-flow_tcf_nl_ack(struct mnl_socket *nl, struct nlmsghdr *nlh)\n+flow_tcf_nl_ack(struct mlx5_tcf_socket *tcf, struct nlmsghdr *nlh)\n {\n \talignas(struct nlmsghdr)\n-\tuint8_t ans[mnl_nlmsg_size(sizeof(struct nlmsgerr)) +\n-\t\t    nlh->nlmsg_len - sizeof(*nlh)];\n-\tuint32_t seq = random();\n-\tint ret;\n-\n+\tuint8_t ans[MNL_SOCKET_BUFFER_SIZE];\n+\tunsigned int portid = mnl_socket_get_portid(tcf->nl);\n+\tuint32_t seq = tcf->seq++;\n+\tstruct mnl_socket *nl = tcf->nl;\n+\tint err, ret;\n+\n+\tassert(nl);\n+\tif (!seq)\n+\t\tseq = tcf->seq++;\n \tnlh->nlmsg_flags |= NLM_F_ACK;\n \tnlh->nlmsg_seq = seq;\n \tret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len);\n-\tif (ret != -1)\n-\t\tret = mnl_socket_recvfrom(nl, ans, sizeof(ans));\n-\tif (ret != -1)\n-\t\tret = mnl_cb_run\n-\t\t\t(ans, ret, seq, mnl_socket_get_portid(nl), NULL, NULL);\n+\terr = (ret <= 0) ? -errno : 0;\n+\tnlh = (struct nlmsghdr *)ans;\n+\t/*\n+\t * The following loop postpones non-fatal errors until multipart\n+\t * messages are complete.\n+\t */\n \tif (ret > 0)\n+\t\twhile (true) {\n+\t\t\tret = mnl_socket_recvfrom(nl, ans, sizeof(ans));\n+\t\t\tif (ret < 0) {\n+\t\t\t\terr = errno;\n+\t\t\t\tif (err != ENOSPC)\n+\t\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (!err) {\n+\t\t\t\tret = mnl_cb_run(nlh, ret, seq, portid,\n+\t\t\t\t\t\t NULL, NULL);\n+\t\t\t\tif (ret < 0) {\n+\t\t\t\t\terr = errno;\n+\t\t\t\t\tbreak;\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\t/* Will receive till end of multipart message */\n+\t\t\tif (!(nlh->nlmsg_flags & NLM_F_MULTI) ||\n+\t\t\t      nlh->nlmsg_type == NLMSG_DONE)\n+\t\t\t\tbreak;\n+\t\t}\n+\tif (!err)\n \t\treturn 0;\n-\trte_errno = errno;\n-\treturn -rte_errno;\n+\trte_errno = err;\n+\treturn -err;\n+}\n+\n+/**\n+ * Initialize ingress qdisc of a given network interface.\n+ *\n+ * @param tcf\n+ *   Libmnl socket context object.\n+ * @param ifindex\n+ *   Index of network interface to initialize.\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+int\n+mlx5_flow_tcf_ifindex_init(struct mlx5_tcf_socket *tcf, unsigned int ifindex,\n+\t\t   struct rte_flow_error *error)\n+{\n+\tstruct nlmsghdr *nlh;\n+\tstruct tcmsg *tcm;\n+\talignas(struct nlmsghdr)\n+\tuint8_t buf[mnl_nlmsg_size(sizeof(*tcm) + 128)];\n+\n+\t/* Destroy existing ingress qdisc and everything attached to it. */\n+\tnlh = mnl_nlmsg_put_header(buf);\n+\tnlh->nlmsg_type = RTM_DELQDISC;\n+\tnlh->nlmsg_flags = NLM_F_REQUEST;\n+\ttcm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tcm));\n+\ttcm->tcm_family = AF_UNSPEC;\n+\ttcm->tcm_ifindex = ifindex;\n+\ttcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);\n+\ttcm->tcm_parent = TC_H_INGRESS;\n+\t/* Ignore errors when qdisc is already absent. */\n+\tif (flow_tcf_nl_ack(tcf, nlh) &&\n+\t    rte_errno != EINVAL && rte_errno != ENOENT)\n+\t\treturn rte_flow_error_set(error, rte_errno,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t  \"netlink: failed to remove ingress\"\n+\t\t\t\t\t  \" qdisc\");\n+\t/* Create fresh ingress qdisc. */\n+\tnlh = mnl_nlmsg_put_header(buf);\n+\tnlh->nlmsg_type = RTM_NEWQDISC;\n+\tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;\n+\ttcm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tcm));\n+\ttcm->tcm_family = AF_UNSPEC;\n+\ttcm->tcm_ifindex = ifindex;\n+\ttcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);\n+\ttcm->tcm_parent = TC_H_INGRESS;\n+\tmnl_attr_put_strz_check(nlh, sizeof(buf), TCA_KIND, \"ingress\");\n+\tif (flow_tcf_nl_ack(tcf, nlh))\n+\t\treturn rte_flow_error_set(error, rte_errno,\n+\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n+\t\t\t\t\t  \"netlink: failed to create ingress\"\n+\t\t\t\t\t  \" qdisc\");\n+\treturn 0;\n }\n \n /**\n@@ -1602,18 +1684,25 @@ struct flow_tcf_ptoi {\n \t       struct rte_flow_error *error)\n {\n \tstruct priv *priv = dev->data->dev_private;\n-\tstruct mnl_socket *nl = priv->mnl_socket;\n+\tstruct mlx5_tcf_socket *tcf = &priv->tcf_socket;\n \tstruct mlx5_flow *dev_flow;\n \tstruct nlmsghdr *nlh;\n+\tint ret;\n \n \tdev_flow = LIST_FIRST(&flow->dev_flows);\n \t/* E-Switch flow can't be expanded. */\n \tassert(!LIST_NEXT(dev_flow, next));\n+\tif (dev_flow->tcf.applied)\n+\t\treturn 0;\n \tnlh = dev_flow->tcf.nlh;\n \tnlh->nlmsg_type = RTM_NEWTFILTER;\n \tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;\n-\tif (!flow_tcf_nl_ack(nl, nlh))\n+\tret = flow_tcf_nl_ack(tcf, nlh);\n+\tif (!ret) {\n+\t\tdev_flow->tcf.applied = 1;\n \t\treturn 0;\n+\t}\n+\tDRV_LOG(WARNING, \"Failed to create TC rule (%d)\", rte_errno);\n \treturn rte_flow_error_set(error, rte_errno,\n \t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n \t\t\t\t  \"netlink: failed to create TC flow rule\");\n@@ -1631,7 +1720,7 @@ struct flow_tcf_ptoi {\n flow_tcf_remove(struct rte_eth_dev *dev, struct rte_flow *flow)\n {\n \tstruct priv *priv = dev->data->dev_private;\n-\tstruct mnl_socket *nl = priv->mnl_socket;\n+\tstruct mlx5_tcf_socket *tcf = &priv->tcf_socket;\n \tstruct mlx5_flow *dev_flow;\n \tstruct nlmsghdr *nlh;\n \n@@ -1645,7 +1734,8 @@ struct flow_tcf_ptoi {\n \tnlh = dev_flow->tcf.nlh;\n \tnlh->nlmsg_type = RTM_DELTFILTER;\n \tnlh->nlmsg_flags = NLM_F_REQUEST;\n-\tflow_tcf_nl_ack(nl, nlh);\n+\tflow_tcf_nl_ack(tcf, nlh);\n+\tdev_flow->tcf.applied = 0;\n }\n \n /**\n@@ -1683,93 +1773,45 @@ struct flow_tcf_ptoi {\n };\n \n /**\n- * Initialize ingress qdisc of a given network interface.\n- *\n- * @param nl\n- *   Libmnl socket of the @p NETLINK_ROUTE kind.\n- * @param ifindex\n- *   Index of network interface to initialize.\n- * @param[out] error\n- *   Perform verbose error reporting if not NULL.\n+ * Creates and configures a libmnl socket for Netlink flow rules.\n  *\n+ * @param tcf\n+ *   tcf socket object to be initialized by function.\n  * @return\n  *   0 on success, a negative errno value otherwise and rte_errno is set.\n  */\n int\n-mlx5_flow_tcf_init(struct mnl_socket *nl, unsigned int ifindex,\n-\t\t   struct rte_flow_error *error)\n-{\n-\tstruct nlmsghdr *nlh;\n-\tstruct tcmsg *tcm;\n-\talignas(struct nlmsghdr)\n-\tuint8_t buf[mnl_nlmsg_size(sizeof(*tcm) + 128)];\n-\n-\t/* Destroy existing ingress qdisc and everything attached to it. */\n-\tnlh = mnl_nlmsg_put_header(buf);\n-\tnlh->nlmsg_type = RTM_DELQDISC;\n-\tnlh->nlmsg_flags = NLM_F_REQUEST;\n-\ttcm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tcm));\n-\ttcm->tcm_family = AF_UNSPEC;\n-\ttcm->tcm_ifindex = ifindex;\n-\ttcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);\n-\ttcm->tcm_parent = TC_H_INGRESS;\n-\t/* Ignore errors when qdisc is already absent. */\n-\tif (flow_tcf_nl_ack(nl, nlh) &&\n-\t    rte_errno != EINVAL && rte_errno != ENOENT)\n-\t\treturn rte_flow_error_set(error, rte_errno,\n-\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n-\t\t\t\t\t  \"netlink: failed to remove ingress\"\n-\t\t\t\t\t  \" qdisc\");\n-\t/* Create fresh ingress qdisc. */\n-\tnlh = mnl_nlmsg_put_header(buf);\n-\tnlh->nlmsg_type = RTM_NEWQDISC;\n-\tnlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;\n-\ttcm = mnl_nlmsg_put_extra_header(nlh, sizeof(*tcm));\n-\ttcm->tcm_family = AF_UNSPEC;\n-\ttcm->tcm_ifindex = ifindex;\n-\ttcm->tcm_handle = TC_H_MAKE(TC_H_INGRESS, 0);\n-\ttcm->tcm_parent = TC_H_INGRESS;\n-\tmnl_attr_put_strz_check(nlh, sizeof(buf), TCA_KIND, \"ingress\");\n-\tif (flow_tcf_nl_ack(nl, nlh))\n-\t\treturn rte_flow_error_set(error, rte_errno,\n-\t\t\t\t\t  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,\n-\t\t\t\t\t  \"netlink: failed to create ingress\"\n-\t\t\t\t\t  \" qdisc\");\n-\treturn 0;\n-}\n-\n-/**\n- * Create and configure a libmnl socket for Netlink flow rules.\n- *\n- * @return\n- *   A valid libmnl socket object pointer on success, NULL otherwise and\n- *   rte_errno is set.\n- */\n-struct mnl_socket *\n-mlx5_flow_tcf_socket_create(void)\n+mlx5_flow_tcf_socket_open(struct mlx5_tcf_socket *tcf)\n {\n \tstruct mnl_socket *nl = mnl_socket_open(NETLINK_ROUTE);\n \n+\ttcf->nl = NULL;\n \tif (nl) {\n \t\tmnl_socket_setsockopt(nl, NETLINK_CAP_ACK, &(int){ 1 },\n \t\t\t\t      sizeof(int));\n-\t\tif (!mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID))\n-\t\t\treturn nl;\n+\t\tif (!mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID)) {\n+\t\t\ttcf->nl = nl;\n+\t\t\ttcf->seq = random();\n+\t\t\treturn 0;\n+\t\t}\n \t}\n \trte_errno = errno;\n \tif (nl)\n \t\tmnl_socket_close(nl);\n-\treturn NULL;\n+\treturn -rte_errno;\n }\n \n /**\n- * Destroy a libmnl socket.\n+ * Destroys tcf object (closes MNL socket).\n  *\n- * @param nl\n- *   Libmnl socket of the @p NETLINK_ROUTE kind.\n+ * @param tcf\n+ *   tcf socket object to be destroyed by function.\n  */\n void\n-mlx5_flow_tcf_socket_destroy(struct mnl_socket *nl)\n+mlx5_flow_tcf_socket_close(struct mlx5_tcf_socket *tcf)\n {\n-\tmnl_socket_close(nl);\n+\tif (tcf->nl) {\n+\t\tmnl_socket_close(tcf->nl);\n+\t\ttcf->nl = NULL;\n+\t}\n }\n",
    "prefixes": [
        "2/5"
    ]
}