get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 64668,
    "url": "http://patches.dpdk.org/api/patches/64668/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20200114142517.29522-2-aostruszka@marvell.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20200114142517.29522-2-aostruszka@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200114142517.29522-2-aostruszka@marvell.com",
    "date": "2020-01-14T14:25:15",
    "name": "[RFC,1/3] lib: introduce IF proxy library (API)",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "9072580bcc139da2ce0bc60992bbd4c03ea05ceb",
    "submitter": {
        "id": 1429,
        "url": "http://patches.dpdk.org/api/people/1429/?format=api",
        "name": "Andrzej Ostruszka [C]",
        "email": "aostruszka@marvell.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20200114142517.29522-2-aostruszka@marvell.com/mbox/",
    "series": [
        {
            "id": 8119,
            "url": "http://patches.dpdk.org/api/series/8119/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=8119",
            "date": "2020-01-14T14:25:14",
            "name": "introduce IF proxy library",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/8119/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/64668/comments/",
    "check": "warning",
    "checks": "http://patches.dpdk.org/api/patches/64668/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@inbox.dpdk.org",
        "Delivered-To": "patchwork@inbox.dpdk.org",
        "Received": [
            "from dpdk.org (dpdk.org [92.243.14.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id B19FDA04FF;\n\tTue, 14 Jan 2020 15:25:34 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id A0B3C1C1AB;\n\tTue, 14 Jan 2020 15:25:26 +0100 (CET)",
            "from mx0b-0016f401.pphosted.com (mx0a-0016f401.pphosted.com\n [67.231.148.174]) by dpdk.org (Postfix) with ESMTP id 91D731C1A5\n for <dev@dpdk.org>; Tue, 14 Jan 2020 15:25:25 +0100 (CET)",
            "from pps.filterd (m0045849.ppops.net [127.0.0.1])\n by mx0a-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id\n 00EEKUmO013360 for <dev@dpdk.org>; Tue, 14 Jan 2020 06:25:24 -0800",
            "from sc-exch01.marvell.com ([199.233.58.181])\n by mx0a-0016f401.pphosted.com with ESMTP id 2xhc6sgngc-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n for <dev@dpdk.org>; Tue, 14 Jan 2020 06:25:24 -0800",
            "from SC-EXCH03.marvell.com (10.93.176.83) by SC-EXCH01.marvell.com\n (10.93.176.81) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Tue, 14 Jan\n 2020 06:25:22 -0800",
            "from maili.marvell.com (10.93.176.43) by SC-EXCH03.marvell.com\n (10.93.176.83) with Microsoft SMTP Server id 15.0.1497.2 via Frontend\n Transport; Tue, 14 Jan 2020 06:25:22 -0800",
            "from amok.marvell.com (unknown [10.95.130.253])\n by maili.marvell.com (Postfix) with ESMTP id 4D3E43F7040;\n Tue, 14 Jan 2020 06:25:21 -0800 (PST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : cc :\n subject : date : message-id : in-reply-to : references : mime-version :\n content-transfer-encoding : content-type; s=pfpt0818;\n bh=YsQqc2Hj+Nvgdb5LVljYpZyCMMyAbbPYlzxjM07aWZk=;\n b=mP284PMJShHzqvO07jPZZO2SEiDwBrVL4CEzv+WZKKnpsIWU4ReIEZyAJZl2bvewzPUn\n Evrs/qHSKfZGO/nqEiSh8rL1guOTrWEMg5hbvpZStKM25+Noy6rgcIDkc5jBLQJAkQdh\n al3v+ekhDsRXNZdupa5BEx6E+8Wmvj8gojjRnBy0QyDjwzq5lFA3RMm8/uvh2ZQOR6pb\n nHjBm/rKIZRfqdWVXNeMyE2GOTckTma6VELmAszQ3jolcv2FzMb0UAKhUylO85eLfUKM\n 1cqwjSPfAcQs2XCYEFXxHXHj3KhVLHVThzoV4vLP5DwDpPdZM8aGtV/h1k3QQK8DmwOv 1g==",
        "From": "Andrzej Ostruszka <aostruszka@marvell.com>",
        "To": "<dev@dpdk.org>",
        "CC": "Jerin Jacob Kollanukkaran <jerinj@marvell.com>, Nithin Kumar Dabilpuram\n <ndabilpuram@marvell.com>, Pavan Nikhilesh Bhagavatula\n <pbhagavatula@marvell.com>, Kiran Kumar Kokkilagadda\n <kirankumark@marvell.com>, Krzysztof Kanas <kkanas@marvell.com>",
        "Date": "Tue, 14 Jan 2020 15:25:15 +0100",
        "Message-ID": "<20200114142517.29522-2-aostruszka@marvell.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "In-Reply-To": "<20200114142517.29522-1-aostruszka@marvell.com>",
        "References": "<20200114142517.29522-1-aostruszka@marvell.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "Content-Type": "text/plain",
        "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10434:6.0.138, 18.0.572\n definitions=2020-01-14_04:2020-01-13,\n 2020-01-14 signatures=0",
        "Subject": "[dpdk-dev] [RFC PATCH 1/3] lib: introduce IF proxy library (API)",
        "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 <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "This library allows to designate ports visible to the system (such as\nTun/Tap or KNI) as port representors serving as proxies for other DPDK\nports.  When such a proxy is configured this library initially queries\nnetwork configuration from the system and later monitors its changes.\n\nThe information gathered is passed to the application via a set of user\nregistered callbacks.  This way user can use normal network utilities\n(like those from the iproute2 suite) to configure DPDK ports.\n\nSigned-off-by: Andrzej Ostruszka <aostruszka@marvell.com>\n---\n lib/librte_if_proxy/rte_if_proxy.h | 364 +++++++++++++++++++++++++++++\n 1 file changed, 364 insertions(+)\n create mode 100644 lib/librte_if_proxy/rte_if_proxy.h",
    "diff": "diff --git a/lib/librte_if_proxy/rte_if_proxy.h b/lib/librte_if_proxy/rte_if_proxy.h\nnew file mode 100644\nindex 000000000..83895d8b7\n--- /dev/null\n+++ b/lib/librte_if_proxy/rte_if_proxy.h\n@@ -0,0 +1,364 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(C) 2020 Marvell International Ltd.\n+ */\n+\n+#ifndef _RTE_IF_PROXY_H_\n+#define _RTE_IF_PROXY_H_\n+\n+/**\n+ * @file\n+ * RTE IF Proxy library\n+ *\n+ * The IF Proxy library allows for monitoring of system network configuration\n+ * and configuration of DPDK ports by using usual system utilities (like the\n+ * ones from iproute2 package).\n+ *\n+ * It is based on the notion of \"proxy interface\" which actually can be any DPDK\n+ * port which is also visible to the system - that is it has non-zero 'if_index'\n+ * field in 'rte_eth_dev_info' structure.\n+ *\n+ * If application doesn't have any such port (or doesn't want to use it for\n+ * proxy) it can create one by calling:\n+ *\n+ *   proxy_id = rte_ifpx_create(RTE_IFPX_DEFAULT);\n+ *\n+ * This function is just a wrapper that constructs valid 'devargs' string based\n+ * on the proxy type chosen (currently Tap or KNI) and creates the interface by\n+ * calling rte_ifpx_dev_create().\n+ *\n+ * Once one has DPDK port capable of being proxy one can bind target DPDK port\n+ * to it by calling.\n+ *\n+ *   rte_ifpx_port_bind(port_id, proxy_id);\n+ *\n+ * This binding is a logical one - there is no automatic packet forwarding\n+ * between port and it's proxy since the library doesn't know the structure of\n+ * application's packet processing.  It remains application responsibility to\n+ * forward the packets from/to proxy port (by calling the usual DPDK RX/TX burst\n+ * API).  However when the library notes some change to the proxy interface it\n+ * will simply call appropriate callback with 'port_id' of the DPDK port that is\n+ * bound to this proxy interface.  The binding can be 1 to many - that is many\n+ * ports can point to one proxy - in that case registered callbacks will be\n+ * called for every bound port.\n+ *\n+ * The callbacks that are used for notifications are described by the\n+ * 'rte_ifpx_callbacks' structure and they are registered by calling:\n+ *\n+ *   rte_ifpx_callbacks_register(&cbs);\n+ *\n+ * Finally the application should call:\n+ *\n+ *   rte_ifpx_listen();\n+ *\n+ * which will query system for present network configuration and start listening\n+ * to its changes.\n+ */\n+\n+#include <rte_eal.h>\n+#include <rte_ethdev.h>\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+/**\n+ * Enum naming the type of proxy to create.\n+ *\n+ * @see rte_ifpx_create()\n+ */\n+enum rte_ifpx_type {\n+    RTE_IFPX_DEFAULT,\t/**< Use default proxy type for given arch. */\n+    RTE_IFPX_TAP,\t/**< Use Tap based port for proxy. */\n+    RTE_IFPX_KNI\t/**< Use KNI based port for proxy. */\n+};\n+\n+/**\n+ * Create DPDK port that can serve as an interface proxy.\n+ *\n+ * This function is just a wrapper around rte_ifpx_create_by_devarg() that\n+ * constructs its 'devarg' argument based on type of proxy requested.\n+ *\n+ * @param type\n+ *   A type of proxy to create.\n+ *\n+ * @return\n+ *   DPDK port id on success, RTE_MAX_ETHPORTS otherwise.\n+ *\n+ * @see enum rte_ifpx_type\n+ * @see rte_ifpx_create_by_devarg()\n+ */\n+__rte_experimental\n+uint16_t rte_ifpx_create(enum rte_ifpx_type type);\n+\n+/**\n+ * Create DPDK port that can serve as an interface proxy.\n+ *\n+ * @param devarg\n+ *   A string passed to rte_dev_probe() to create proxy port.\n+ *\n+ * @return\n+ *   DPDK port id on success, RTE_MAX_ETHPORTS otherwise.\n+ */\n+__rte_experimental\n+uint16_t rte_ifpx_create_by_devarg(const char *devarg);\n+\n+/**\n+ * Remove DPDK proxy port.\n+ *\n+ * In addition to removing the proxy port the bindings (if any) are cleared.\n+ *\n+ * @param proxy_id\n+ *   Port id of the proxy that should be removed.\n+ *\n+ * @return\n+ *   0 on success, negative on error.\n+ */\n+__rte_experimental\n+int rte_ifpx_destroy(uint16_t proxy_id);\n+\n+/**\n+ * This structure groups the callbacks that might be called as a notification\n+ * events for changing network configuration.  Not every platform might\n+ * implement all of them and you can query the availability with\n+ * rte_ifpx_callbacks_available() function and testing each bit against bit mask\n+ * values defined in enum rte_ifpx_cb_bit.\n+ * @see enum rte_ifpx_cb_bit\n+ * @see rte_ifpx_callbacks_available()\n+ * @see rte_ifpx_callbacks_register()\n+ */\n+struct rte_ifpx_callbacks {\n+\tvoid  (*mac_change)(uint16_t port_id, const struct rte_ether_addr *mac);\n+\t/**< Callback for notification about MAC change of the proxy interface.\n+\t * This callback (as all other port related callbacks) is called for\n+\t * each port (with its port_id as a first argument) bound to the proxy\n+\t * interface for which change has been observed.\n+\t * @see RTE_IFPX_MAC_CHANGE\n+\t */\n+\tvoid  (*mtu_change)(uint16_t port_id, uint16_t mtu);\n+\t/**< Callback for notification about MTU change.\n+\t * @see RTE_IFPX_MTU_CHANGE\n+\t */\n+\tvoid (*link_change)(uint16_t port_id, int is_up);\n+\t/**< Callback for notification about link going up/down.\n+\t * @see RTE_IFPX_LINK_CHANGE\n+\t */\n+\t/* All IPv4 addresses are in host order */\n+\tvoid    (*addr_add)(uint16_t port_id, uint32_t ip);\n+\t/**< Callback for notification about IPv4 address being added.\n+\t * @see RTE_IFPX_ADDR_ADD\n+\t */\n+\tvoid    (*addr_del)(uint16_t port_id, uint32_t ip);\n+\t/**< Callback for notification about IPv4 address removal.\n+\t * @see RTE_IFPX_ADDR_DEL\n+\t */\n+\tvoid   (*addr6_add)(uint16_t port_id, const uint8_t *ip);\n+\t/**< Callback for notification about IPv6 address being added.\n+\t * @see RTE_IFPX_ADDR6_ADD\n+\t */\n+\tvoid   (*addr6_del)(uint16_t port_id, const uint8_t *ip);\n+\t/**< Callback for notification about IPv4 address removal.\n+\t * @see RTE_IFPX_ADDR6_DEL\n+\t */\n+\tvoid   (*route_add)(uint32_t ip, uint8_t depth);\n+\t/**< Callback for notification about IPv4 route being added.\n+\t * Note that \"route\" callbacks might be also called when user adds\n+\t * address to the interface (that is in addition to address related\n+\t * callbacks).\n+\t * @see RTE_IFPX_ROUTE_ADD\n+\t */\n+\tvoid   (*route_del)(uint32_t ip, uint8_t depth);\n+\t/**< Callback for notification about IPv4 route removal.\n+\t * @see RTE_IFPX_ROUTE_DEL\n+\t */\n+\tvoid  (*route6_add)(const uint8_t *ip, uint8_t depth);\n+\t/**< Callback for notification about IPv6 route being added.\n+\t * @see RTE_IFPX_ROUTE6_ADD\n+\t */\n+\tvoid  (*route6_del)(const uint8_t *ip, uint8_t depth);\n+\t/**< Callback for notification about IPv6 route removal.\n+\t * @see RTE_IFPX_ROUTE6_DEL\n+\t */\n+\tvoid (*cfg_finished)(void);\n+\t/**< Lib specific callback - called when initial network configuration\n+\t * query is finished.\n+\t */\n+};\n+\n+/**\n+ * The rte_ifpx_cb_bit enum defines bit mask values to test against value\n+ * returned by rte_ifpx_callbacks_available() to learn about type of callbacks\n+ * implemented for this platform.\n+ */\n+enum rte_ifpx_cb_bit {\n+    RTE_IFPX_MAC_CHANGE  = 1ULL << 0,  /**< @see mac_change callback */\n+    RTE_IFPX_MTU_CHANGE  = 1ULL << 1,  /**< @see mtu_change callback */\n+    RTE_IFPX_LINK_CHANGE = 1ULL << 2,  /**< @see link_change callback */\n+    RTE_IFPX_ADDR_ADD    = 1ULL << 3,  /**< @see addr_add callback */\n+    RTE_IFPX_ADDR_DEL    = 1ULL << 4,  /**< @see addr_del callback */\n+    RTE_IFPX_ADDR6_ADD   = 1ULL << 5,  /**< @see addr6_add callback */\n+    RTE_IFPX_ADDR6_DEL   = 1ULL << 6,  /**< @see addr6_del callback */\n+    RTE_IFPX_ROUTE_ADD   = 1ULL << 7,  /**< @see route_add callback */\n+    RTE_IFPX_ROUTE_DEL   = 1ULL << 8,  /**< @see route_del callback */\n+    RTE_IFPX_ROUTE6_ADD  = 1ULL << 9,  /**< @see route6_add callback */\n+    RTE_IFPX_ROUTE6_DEL  = 1ULL << 10, /**< @see route6_del callback */\n+};\n+/**\n+ * Get the bit mask of implemented callbacks for this platform.\n+ *\n+ * @return\n+ *   Bit mask of callbacks implemented.\n+ * @see enum rte_ifpx_cb_bit\n+ */\n+__rte_experimental\n+uint64_t rte_ifpx_callbacks_available(void);\n+\n+/**\n+ * Typedef naming type of value returned during callback registration.\n+ *\n+ * @see rte_ifpx_callbacks_register()\n+ */\n+typedef const void *rte_ifpx_cbs_hndl;\n+\n+/**\n+ * Register proxy callbacks.\n+ *\n+ * This function registers callbacks to be called upon appropriate network\n+ * event notification.\n+ *\n+ * @param cbs\n+ *   Set of callbacks that will be called.  The library does not take any\n+ *   ownership of the pointer passed - the callbacks are stored internally.\n+ *\n+ * @return\n+ *   Non-NULL pointer upon successful registration - that pointer can be used\n+ *   as a handle to unregister callbacks (and nothing more).  On failure NULL\n+ *   is returned.\n+ */\n+__rte_experimental\n+rte_ifpx_cbs_hndl rte_ifpx_callbacks_register(const\n+\t\t\t\t\t      struct rte_ifpx_callbacks *cbs);\n+\n+/**\n+ * Unregister proxy callbacks.\n+ *\n+ * This function unregisters callbacks previously registered with\n+ * rte_ifpx_callbacks_register().\n+ *\n+ * @param cbs\n+ *   Handle/pointer returned on previous callback registration.\n+ *\n+ * @return\n+ *   0 on success, negative otherwise.\n+ */\n+__rte_experimental\n+int rte_ifpx_callbacks_unregister(rte_ifpx_cbs_hndl cbs);\n+\n+/**\n+ * Bind the port to its proxy.\n+ *\n+ * After calling this function all network configuration of the proxy (and it's\n+ * changes) will be passed to given port by calling registered callbacks with\n+ * 'port_id' as an argument.\n+ *\n+ * Note: since both arguments are of the same type in order to not mix them and\n+ * ease remembering the order the first one is kept the same for bind/unbind.\n+ *\n+ * @param port_id\n+ *   Id of the port to be bound.\n+ * @param proxy_id\n+ *   Id of the proxy the port needs to be bound to.\n+ * @return\n+ *   0 on success, negative on error.\n+ */\n+__rte_experimental\n+int rte_ifpx_port_bind(uint16_t port_id, uint16_t proxy_id);\n+\n+/**\n+ * Unbind the port from its proxy.\n+ *\n+ * After calling this function registered callbacks will no longer be called for\n+ * this port (but they might be called for other ports in one to many binding\n+ * scenario).\n+ *\n+ * @param port_id\n+ *   Id of the port to unbind.\n+ * @return\n+ *   0 on success, negative on error.\n+ */\n+__rte_experimental\n+int rte_ifpx_port_unbind(uint16_t port_id);\n+\n+/**\n+ * Get the system network configuration and start listening to its changes.\n+ *\n+ * @return\n+ *   0 on success, negative otherwise.\n+ */\n+__rte_experimental\n+int rte_ifpx_listen(void);\n+\n+/**\n+ * Remove all bindings/callbacks and stop listening to network configuration.\n+ *\n+ * @return\n+ *   0 on success, negative otherwise.\n+ */\n+__rte_experimental\n+int rte_ifpx_close(void);\n+\n+/**\n+ * Get the id of the proxy the port is bound to.\n+ *\n+ * @param port_id\n+ *   Id of the port for which to get proxy.\n+ * @return\n+ *   Port id of the proxy on success, RTE_ETH_MAXPORT on error.\n+ */\n+__rte_experimental\n+uint16_t rte_ifpx_proxy_get(uint16_t port_id);\n+\n+/**\n+ * Get the ids of the ports bound to the proxy.\n+ *\n+ * @param proxy_id\n+ *   Id of the proxy for which to get ports.\n+ * @param ports\n+ *   Array where to store the port ids.\n+ * @param num\n+ *   Size of the 'ports' array.\n+ * @return\n+ *   The number of ports bound to given proxy.  Note that this function return\n+ *   value does not depend on the ports/num argument - so you can call it first\n+ *   with NULL/0 to query for the size of the buffer to create or call it with\n+ *   the buffer you have and later check if it was large enough.\n+ */\n+__rte_experimental\n+unsigned int rte_ifpx_port_get(uint16_t proxy_id,\n+\t\t\t       uint16_t *ports, unsigned int num);\n+\n+/**\n+ * The structure containing some properties of the proxy interface.\n+ */\n+struct rte_ifpx_info {\n+\tunsigned int if_index; /* entry valid iff if_index != 0 */\n+\tuint16_t mtu;\n+\tstruct rte_ether_addr mac;\n+\tchar if_name[RTE_ETH_NAME_MAX_LEN];\n+};\n+\n+/**\n+ * Get the properties of the proxy interface given port is bound to.\n+ *\n+ * @param port_id\n+ *   Id of the port for which to get proxy properties.\n+ * @return\n+ *   Pointer to the proxy information structure.\n+ */\n+__rte_experimental\n+const struct rte_ifpx_info *rte_ifpx_info_get(uint16_t port_id);\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* _RTE_IF_PROXY_H_ */\n",
    "prefixes": [
        "RFC",
        "1/3"
    ]
}