Show a cover letter.

GET /api/covers/66350/?format=api
HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 66350,
    "url": "http://patches.dpdk.org/api/covers/66350/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/cover/20200306164104.15528-1-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": "<20200306164104.15528-1-aostruszka@marvell.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20200306164104.15528-1-aostruszka@marvell.com",
    "date": "2020-03-06T16:41:00",
    "name": "[0/4] Introduce IF proxy library",
    "submitter": {
        "id": 1429,
        "url": "http://patches.dpdk.org/api/people/1429/?format=api",
        "name": "Andrzej Ostruszka [C]",
        "email": "aostruszka@marvell.com"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/cover/20200306164104.15528-1-aostruszka@marvell.com/mbox/",
    "series": [
        {
            "id": 8820,
            "url": "http://patches.dpdk.org/api/series/8820/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=8820",
            "date": "2020-03-06T16:41:00",
            "name": "Introduce IF proxy library",
            "version": 1,
            "mbox": "http://patches.dpdk.org/series/8820/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/covers/66350/comments/",
    "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 F2E8DA056A;\n\tFri,  6 Mar 2020 17:41:12 +0100 (CET)",
            "from [92.243.14.124] (localhost [127.0.0.1])\n\tby dpdk.org (Postfix) with ESMTP id EEABA1BFBB;\n\tFri,  6 Mar 2020 17:41:11 +0100 (CET)",
            "from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com\n [67.231.156.173]) by dpdk.org (Postfix) with ESMTP id 6F88023D\n for <dev@dpdk.org>; Fri,  6 Mar 2020 17:41:10 +0100 (CET)",
            "from pps.filterd (m0045851.ppops.net [127.0.0.1])\n by mx0b-0016f401.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id\n 026FwMMj026250 for <dev@dpdk.org>; Fri, 6 Mar 2020 08:41:09 -0800",
            "from sc-exch03.marvell.com ([199.233.58.183])\n by mx0b-0016f401.pphosted.com with ESMTP id 2yhn0ydvr2-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT)\n for <dev@dpdk.org>; Fri, 06 Mar 2020 08:41:09 -0800",
            "from DC5-EXCH02.marvell.com (10.69.176.39) by SC-EXCH03.marvell.com\n (10.93.176.83) with Microsoft SMTP Server (TLS) id 15.0.1497.2;\n Fri, 6 Mar 2020 08:41:07 -0800",
            "from SC-EXCH01.marvell.com (10.93.176.81) by DC5-EXCH02.marvell.com\n (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.2;\n Fri, 6 Mar 2020 08:41:07 -0800",
            "from maili.marvell.com (10.93.176.43) by SC-EXCH01.marvell.com\n (10.93.176.81) with Microsoft SMTP Server id 15.0.1497.2 via Frontend\n Transport; Fri, 6 Mar 2020 08:41:06 -0800",
            "from amok.marvell.com (unknown [10.95.130.79])\n by maili.marvell.com (Postfix) with ESMTP id 0BB473F7040\n for <dev@dpdk.org>; Fri,  6 Mar 2020 08:41:05 -0800 (PST)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com;\n h=from : to : subject\n : date : message-id : mime-version : content-transfer-encoding :\n content-type; s=pfpt0818; bh=MqT5lloSqZxbWnYZac3Vp+jfo9+YXHxuL1dYx2mv5KI=;\n b=bgdvfvYgXQqnj02zl5WHb4d3g30zYv8uVqh7V49ixp5Of3OxgkBvBXdHghAXF/8gCCBh\n lqwI/LXcp19iBftQEF3ESwhxuQ+Y0y1s3jeRvCpIH0wapKQXkyc+9aPGtQp3MXtfcrPn\n 94y7H/qXNltpeWIf0F2/yBz63aaQMwuTgOPgFxORRmBQyWciIYeNOjvAX+Nk3qzDBv8H\n Z0GlEpxqYZtPLVU3nd93spWr3ikIrvp5ezmOZvLgiycqWDwnaMVCLsUxPkow0mmjrgTa\n I2BzlVkIeCYrWmA5EYgUTwNvnTPmJpsXLCOa7VkPJ0ytzLldVxJtH8ANI6NQUJK2I2u8 3g==",
        "From": "Andrzej Ostruszka <aostruszka@marvell.com>",
        "To": "<dev@dpdk.org>",
        "Date": "Fri, 6 Mar 2020 17:41:00 +0100",
        "Message-ID": "<20200306164104.15528-1-aostruszka@marvell.com>",
        "X-Mailer": "git-send-email 2.17.1",
        "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-03-06_05:2020-03-06,\n 2020-03-06 signatures=0",
        "Subject": "[dpdk-dev] [PATCH 0/4] Introduce IF proxy library",
        "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": "What is this useful for\n=======================\n\nUsually, when an ethernet port is assigned to DPDK it vanishes from the\nsystem and user looses ability to control it via normal configuration\nutilities (e.g. those from iproute2 package).  Moreover by default DPDK\napplication is not aware of the network configuration of the system.\n\nTo address both of these issues application needs to:\n- add some command line interface (or other mechanism) allowing for\n  control of the port and its configuration\n- query the status of network configuration and monitor its changes\n\nThe purpose of this library is to help with both of these tasks (as long\nas they remain in domain of configuration available to the system).  In\nother words, if DPDK application has some special needs, that cannot be\naddressed by the normal system configuration utilities, then they need\nto be solved by the application itself.\n\nThe connection between DPDK and system is based on the existence of\nports that are visible to both DPDK and system (like Tap, KNI and\npossibly some other drivers).  These ports serve as an interface\nproxies.\n\nLet's visualize the action of the library by the following example:\n\n              Linux             |            DPDK\n==============================================================\n                                |\n                                |   +-------+       +-------+\n                                |   | Port1 |       | Port2 |\n\"ip link set dev tap1 mtu 1600\" |   +-------+       +-------+\n                          |     |       ^              ^ ^\n                          |  +------+   | mtu_change   | |\n                          `->| Tap1 |---' callback     | |\n                             +------+                  | |\n\"ip addr add 198.51.100.14 \\    |                      | |\n                  dev tap2\"     |                      | |\n                          |  +------+                  | |\n                          +->| Tap2 |------------------' |\n                          |  +------+  addr_add callback |\n\"ip route add 198.0.2.0/24 \\    |  |                     |\n                  dev tap2\"     |  | route_add callback  |\n                                |  `---------------------'\n\nSo we have two ports Port1 and Port2 that are not visible to the system.\nWe create two proxy interfaces (here based on Tap driver) and bind the\nports to their proxies.  When user issues a command changing MTU for\nTap1 interface the library notes this and calls \"mtu_change\" callback\nfor the Port1.  Similarly when user adds an IPv4 address to the Tap2\ninterface \"addr_add\" callback is called for the Port2 and the same\nhappens for configuration of routing rule pointing to Tap2.  Apart from\ncallbacks this library can notify about changes via adding events to\nnotification queues.  See below for more inforamtion about that and\na complete list of available callbacks.\n\nPlease note that nothing has been mentioned about forwarding of the\npackets between system and DPDK.  Since the proxies are normal DPDK\nports you can receive/send to them via usual RX/TX burst API.  However\nsince the library is not aware of the structure of packet processing\nused by the application it cannot automatically forward the packets - it\nis responsibility of the application to include proxy ports into its\npacket processing engine.\n\nAs mentioned above the intention of the library is to:\n- provide information about network configuration that would allow\n  application to decide what to do with the packets received on DPDK\n  ports,\n- allow for control of the ports via standard configuration utilities\n\nAlthough the library only helps you to identify proxy for given port\n(and vice versa) and calls appropriate callbacks it does open some\ninteresting possibilities.  For example you can use the proxy ports to\nforward packets for protocols that you do not wish to handle in DPDK\napplication to the system protocol stack and just listen to the\nconfiguration changes - so that way you can \"offload\" handling of those\nprotocols to the system.\n\nHow to use it\n=============\n\nUsage of this library is rather simple.  You have to:\n1. Create proxy (if you don't have port suitable for being proxy or you\n  have one but do not wish to use it as a proxy).\n2. Bind port to proxy.\n3. Register callbacks and/or event queues.\n4. Start listening to the network configuration.\n\nThe only mandatory requirement for DPDK port to be able to act as\na proxy is that it is visible in the system - this is checked during\nport to proxy binding by calling rte_eth_dev_info_get() on proxy port\nand inspecting 'if_index' field (it has to be non-zero).\nOne can create such port in the application by calling:\n\n  proxy_id = rte_ifpx_create(RTE_IFPX_DEFAULT);\n\nUpon success this returns id of DPDK proxy port created\n(RTE_MAX_ETHPORTS on failure).  The argument selects type of proxy port\nto create (currently Tap/KNI only).  This function actually is just\na wrapper around:\n\n  uint16_t rte_ifpx_create_by_devarg(const char *devarg);\n\ncreating valid 'devarg' string for the chosen type of proxy.  If you have\nother driver capable of acting as a proxy you can call\nrte_ifpx_create_by_devarg() directly passing appropriate argument.\n\nOnce you have id of both port and proxy you can bind the two via:\n\n  rte_ifpx_port_bind(port_id, proxy_id);\n\nThis creates logical binding - as mentioned above there is no automatic\npacket forwarding.  With this binding whenever user changes the state of\nproxy interface in the system (link up/down, change mac/mtu, add/remove\nIPv4/IPv6) you get appropriate notification for the bound port.\n\nSo far we've mentioned several times that the library calls callbacks.\nThey are grouped in 'struct rte_ifpx_callbacks' and user provides them\nto the library via:\n\n  rte_ifpx_callbacks_register(&cbs);\n\nIt is worth mentioning that the context (lcore/thread) in which these\ncallbacks are called is implementation defined.  It might differ between\ndifferent platforms, so the application needs to assume that some kind\nof inter lcore/thread synchronization/communication is required.\n\nApart from notification via callbacks this library also supports\nnotifying about the changes via adding events to the configured\nnotification queues.  The queues are registered via:\n\n  int rte_ifpx_queue_add(struct rte_ring *r);\n\nand the actual logic used is: if there is callback registered then it is\ncalled, if it returns non-zero then event is considered completed,\notherwise event is added to each configured notification queue.\nThat way application can update data structures that are safe to be\nmodified by single writer from within callback or do the common\npreprocessing steps (if any needed) in callback and data that is\nreplicated can be updated during handling of queued events.\n\nOnce we have bindings in place and notification configured, the only\nessential part that remains is to get the current network configuration\nand start listening to its changes.  This is accomplished via a call to:\n\n  rte_ifpx_listen();\n\nAnd basically this is all one needs to understand how to use this\nlibrary.  Other less essential parts include:\n- ability to query what events are available for given platform\n- getting mapping between proxy and port\n- unbinding the ports from proxy\n- destroying proxy port\n- closing the listening service\n- getting basic information about proxy\n\n\nCurrently available features and implementation\n===============================================\n\nThe library's API is system independent but it obviously needs some\nsystem dependent parts.  We provide exemplary Linux implementation (based\non netlink sockets).  Very similar implementation is possible for\nFreeBSD (with the usage of PF_ROUTE sockets).  Windows implementation\nwould need to differ much (probably IP Helper library would be of some help).\n\nHere is the list of currently implemented callbacks:\n\nstruct rte_ifpx_callbacks {\n  int (*mac_change)(const struct rte_ifpx_mac_change *event);\n  int (*mtu_change)(const struct rte_ifpx_mtu_change *event);\n  int (*link_change)(const struct rte_ifpx_link_change *event);\n  int (*addr_add)(const struct rte_ifpx_addr_change *event);\n  int (*addr_del)(const struct rte_ifpx_addr_change *event);\n  int (*addr6_add)(const struct rte_ifpx_addr6_change *event);\n  int (*addr6_del)(const struct rte_ifpx_addr6_change *event);\n  int (*route_add)(const struct rte_ifpx_route_change *event);\n  int (*route_del)(const struct rte_ifpx_route_change *event);\n  int (*route6_add)(const struct rte_ifpx_route6_change *event);\n  int (*route6_del)(const struct rte_ifpx_route6_change *event);\n  int (*neigh_add)(const struct rte_ifpx_neigh_change *event);\n  int (*neigh_del)(const struct rte_ifpx_neigh_change *event);\n  int (*neigh6_add)(const struct rte_ifpx_neigh6_change *event);\n  int (*neigh6_del)(const struct rte_ifpx_neigh6_change *event);\n  int (*cfg_done)(void);\n};\n\nThey are all rather self-descriptive with the exception of the last one.\nWhen the user calls rte_ifpx_listen() the library first queries the\nsystem for its current configuration.  That might require several\nrequest/reply exchanges between DPDK and system and once it is finished\nthis callback is called to let application know that all info has been\ngathered.\n\nIt is worth to mention also that while typical case would be a 1-to-1\nmapping between port and proxy, the 1-to-many mapping is also supported.\nIn that case port related callbacks will be called for each port bound\nto given proxy interface - in that case it is application responsibility\nto define semantic of such mapping (e.g. all changes apply to all ports,\nor link changes apply to all but other are accepted in \"round robin\"\nfashion, or ...).\n\nAs mentioned above Linux implementation is based on netlink socket.\nThis socket is registered as file descriptor in EAL interrupts\n(similarly to how EAL alarms are implemented).\n\nWhat has changed since the RFC\n==============================\n\n- Platform dependent parts has been separated into a ifpx_platform\n  structure with callbacks for initialization, getting information about\n  the interface, listening to the changes and closing of the library.\n  That should allow easier reimplementation.\n\n- Notification scheme has been changed - instead of having just\n  callbacks now event queueing is also available (or a mix of those\n  two).\n\n- Filtering of events only related to the proxy ports - previously all\n  network configuration changes were reported.  But DPDK application\n  needs not to know all configuration - only just portion related to the\n  proxy ports.  If a packet comes that does not match rules then it can\n  be forwarded via proxy to the system to decide what to do with it.  If\n  that is not desired and such packets should be dropped then null port\n  can be created with proxy and e.g. default route installed on it.\n\n- Removed previous example which was just printing notification.\n  Instead added a simplified (stripped vectorization and other\n  performance improvements) version of l3fwd that should serve as an\n  example of using this library in real applications.\n\nWith regards\nAndrzej Ostruszka\n\nAndrzej Ostruszka (4):\n  lib: introduce IF Proxy library\n  if_proxy: add library documentation\n  if_proxy: add simple functionality test\n  if_proxy: add example application\n\n MAINTAINERS                                   |    6 +\n app/test/Makefile                             |    5 +\n app/test/meson.build                          |    4 +\n app/test/test_if_proxy.c                      |  706 +++++++++++\n config/common_base                            |    5 +\n config/common_linux                           |    1 +\n doc/guides/prog_guide/if_proxy_lib.rst        |  142 +++\n doc/guides/prog_guide/index.rst               |    1 +\n examples/Makefile                             |    1 +\n examples/l3fwd-ifpx/Makefile                  |   60 +\n examples/l3fwd-ifpx/l3fwd.c                   | 1123 +++++++++++++++++\n examples/l3fwd-ifpx/l3fwd.h                   |   98 ++\n examples/l3fwd-ifpx/main.c                    |  729 +++++++++++\n examples/l3fwd-ifpx/meson.build               |   11 +\n examples/meson.build                          |    2 +-\n lib/Makefile                                  |    2 +\n .../common/include/rte_eal_interrupts.h       |    2 +\n lib/librte_eal/linux/eal/eal_interrupts.c     |   14 +-\n lib/librte_if_proxy/Makefile                  |   29 +\n lib/librte_if_proxy/if_proxy_common.c         |  494 ++++++++\n lib/librte_if_proxy/if_proxy_priv.h           |   97 ++\n lib/librte_if_proxy/linux/Makefile            |    4 +\n lib/librte_if_proxy/linux/if_proxy.c          |  552 ++++++++\n lib/librte_if_proxy/meson.build               |   19 +\n lib/librte_if_proxy/rte_if_proxy.h            |  561 ++++++++\n lib/librte_if_proxy/rte_if_proxy_version.map  |   19 +\n lib/meson.build                               |    2 +-\n 27 files changed, 4683 insertions(+), 6 deletions(-)\n create mode 100644 app/test/test_if_proxy.c\n create mode 100644 doc/guides/prog_guide/if_proxy_lib.rst\n create mode 100644 examples/l3fwd-ifpx/Makefile\n create mode 100644 examples/l3fwd-ifpx/l3fwd.c\n create mode 100644 examples/l3fwd-ifpx/l3fwd.h\n create mode 100644 examples/l3fwd-ifpx/main.c\n create mode 100644 examples/l3fwd-ifpx/meson.build\n create mode 100644 lib/librte_if_proxy/Makefile\n create mode 100644 lib/librte_if_proxy/if_proxy_common.c\n create mode 100644 lib/librte_if_proxy/if_proxy_priv.h\n create mode 100644 lib/librte_if_proxy/linux/Makefile\n create mode 100644 lib/librte_if_proxy/linux/if_proxy.c\n create mode 100644 lib/librte_if_proxy/meson.build\n create mode 100644 lib/librte_if_proxy/rte_if_proxy.h\n create mode 100644 lib/librte_if_proxy/rte_if_proxy_version.map"
}