get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 22062,
    "url": "https://patches.dpdk.org/api/patches/22062/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/a145fab8fdec313abeea2b09bbafcca9692bd481.1490171928.git.pascal.mazon@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": "<a145fab8fdec313abeea2b09bbafcca9692bd481.1490171928.git.pascal.mazon@6wind.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/a145fab8fdec313abeea2b09bbafcca9692bd481.1490171928.git.pascal.mazon@6wind.com",
    "date": "2017-03-22T08:40:01",
    "name": "[dpdk-dev,2/2] net/tap: add link status notification",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "a64f1c5097fcfbba86489ecd1c7fb6a5934cfd5f",
    "submitter": {
        "id": 657,
        "url": "https://patches.dpdk.org/api/people/657/?format=api",
        "name": "Pascal Mazon",
        "email": "pascal.mazon@6wind.com"
    },
    "delegate": {
        "id": 319,
        "url": "https://patches.dpdk.org/api/users/319/?format=api",
        "username": "fyigit",
        "first_name": "Ferruh",
        "last_name": "Yigit",
        "email": "ferruh.yigit@amd.com"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/a145fab8fdec313abeea2b09bbafcca9692bd481.1490171928.git.pascal.mazon@6wind.com/mbox/",
    "series": [],
    "comments": "https://patches.dpdk.org/api/patches/22062/comments/",
    "check": "fail",
    "checks": "https://patches.dpdk.org/api/patches/22062/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 B7DEE69A5;\n\tWed, 22 Mar 2017 09:40:17 +0100 (CET)",
            "from proxy.6wind.com (host.76.145.23.62.rev.coltfrance.com\n\t[62.23.145.76]) by dpdk.org (Postfix) with ESMTP id 4ADC91094\n\tfor <dev@dpdk.org>; Wed, 22 Mar 2017 09:40:12 +0100 (CET)",
            "from 6wind.com (unknown [10.16.0.184])\n\tby proxy.6wind.com (Postfix) with SMTP id 56E2D253F5;\n\tWed, 22 Mar 2017 09:40:06 +0100 (CET)",
            "by 6wind.com (sSMTP sendmail emulation);\n\tWed, 22 Mar 2017 09:40:04 +0100"
        ],
        "From": "Pascal Mazon <pascal.mazon@6wind.com>",
        "To": "keith.wiles@intel.com",
        "Cc": "dev@dpdk.org,\n\tPascal Mazon <pascal.mazon@6wind.com>",
        "Date": "Wed, 22 Mar 2017 09:40:01 +0100",
        "Message-Id": "<a145fab8fdec313abeea2b09bbafcca9692bd481.1490171928.git.pascal.mazon@6wind.com>",
        "X-Mailer": "git-send-email 2.12.0.306.g4a9b9b3",
        "In-Reply-To": "<fa9ce2ddc2cac000570b6ed58fa607e235992a3f.1490171928.git.pascal.mazon@6wind.com>",
        "References": "<fa9ce2ddc2cac000570b6ed58fa607e235992a3f.1490171928.git.pascal.mazon@6wind.com>",
        "Subject": "[dpdk-dev] [PATCH 2/2] net/tap: add link status notification",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "DPDK patches and discussions <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": "As tap is a virtual device, there's no physical way a link can be cut.\nHowever, it has an associated kernel netdevice and possibly a remote\nnetdevice too. These netdevices link status may change outside of the\nDPDK scope, through an external command such as:\n\n  ip link set dev tapX down\n\nThis commit implements link status notification through netlink.\n\nSigned-off-by: Pascal Mazon <pascal.mazon@6wind.com>\n---\n doc/guides/nics/features/tap.ini |  1 +\n drivers/net/tap/rte_eth_tap.c    | 65 ++++++++++++++++++++++++++++++++++++++--\n drivers/net/tap/rte_eth_tap.h    |  1 +\n drivers/net/tap/tap_netlink.c    | 11 +++++--\n drivers/net/tap/tap_netlink.h    |  2 +-\n drivers/net/tap/tap_tcmsgs.c     |  2 +-\n 6 files changed, 76 insertions(+), 6 deletions(-)",
    "diff": "diff --git a/doc/guides/nics/features/tap.ini b/doc/guides/nics/features/tap.ini\nindex 9d73f61cca3b..20cbeee72f52 100644\n--- a/doc/guides/nics/features/tap.ini\n+++ b/doc/guides/nics/features/tap.ini\n@@ -5,6 +5,7 @@\n ;\n [Features]\n Link status          = Y\n+Link status event    = Y\n Jumbo frame          = Y\n Promiscuous mode     = Y\n Allmulticast mode    = Y\ndiff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c\nindex 54122fd13c66..6567bba75b47 100644\n--- a/drivers/net/tap/rte_eth_tap.c\n+++ b/drivers/net/tap/rte_eth_tap.c\n@@ -61,6 +61,7 @@\n \n #include <rte_eth_tap.h>\n #include <tap_flow.h>\n+#include <tap_netlink.h>\n #include <tap_tcmsgs.h>\n \n /* Linux based path to the TUN device */\n@@ -111,6 +112,8 @@ static int\n tap_ioctl(struct pmd_internals *pmd, unsigned long request,\n \t  struct ifreq *ifr, int set);\n \n+static int tap_intr_handle_set(struct rte_eth_dev *dev, int set);\n+\n /* Tun/Tap allocation routine\n  *\n  * name is the number of the interface to use, unless NULL to take the host\n@@ -520,6 +523,11 @@ tap_link_set_up(struct rte_eth_dev *dev)\n static int\n tap_dev_start(struct rte_eth_dev *dev)\n {\n+\tint err;\n+\n+\terr = tap_intr_handle_set(dev, 1);\n+\tif (err)\n+\t\treturn err;\n \treturn tap_link_set_up(dev);\n }\n \n@@ -528,6 +536,7 @@ tap_dev_start(struct rte_eth_dev *dev)\n static void\n tap_dev_stop(struct rte_eth_dev *dev)\n {\n+\ttap_intr_handle_set(dev, 0);\n \ttap_link_set_down(dev);\n }\n \n@@ -976,6 +985,55 @@ tap_set_mc_addr_list(struct rte_eth_dev *dev __rte_unused,\n \treturn 0;\n }\n \n+static int\n+tap_nl_msg_handler(struct nlmsghdr *nh, void *arg)\n+{\n+\tstruct rte_eth_dev *dev = arg;\n+\tstruct pmd_internals *pmd = dev->data->dev_private;\n+\tstruct ifinfomsg *info = NLMSG_DATA(nh);\n+\n+\tif (nh->nlmsg_type != RTM_NEWLINK ||\n+\t    (info->ifi_index != pmd->if_index &&\n+\t     info->ifi_index != pmd->remote_if_index))\n+\t\treturn 0;\n+\treturn tap_link_update(dev, 0);\n+}\n+\n+static void\n+tap_dev_intr_handler(struct rte_intr_handle *intr_handle __rte_unused,\n+\t\t     void *cb_arg)\n+{\n+\tstruct rte_eth_dev *dev = cb_arg;\n+\tstruct pmd_internals *pmd = dev->data->dev_private;\n+\n+\tnl_recv(pmd->intr_handle.fd, tap_nl_msg_handler, dev);\n+}\n+\n+static int\n+tap_intr_handle_set(struct rte_eth_dev *dev, int set)\n+{\n+\tstruct pmd_internals *pmd = dev->data->dev_private;\n+\n+\t/* In any case, disable interrupt if the conf is no longer there. */\n+\tif (!dev->data->dev_conf.intr_conf.lsc) {\n+\t\tif (pmd->intr_handle.fd != -1)\n+\t\t\tnl_final(pmd->intr_handle.fd);\n+\t\trte_intr_callback_unregister(\n+\t\t\t&pmd->intr_handle, tap_dev_intr_handler, dev);\n+\t\treturn 0;\n+\t}\n+\tif (set) {\n+\t\tpmd->intr_handle.fd = nl_init(RTMGRP_LINK);\n+\t\tif (unlikely(pmd->intr_handle.fd == -1))\n+\t\t\treturn -EBADF;\n+\t\treturn rte_intr_callback_register(\n+\t\t\t&pmd->intr_handle, tap_dev_intr_handler, dev);\n+\t}\n+\tnl_final(pmd->intr_handle.fd);\n+\treturn rte_intr_callback_unregister(&pmd->intr_handle,\n+\t\t\t\t\t    tap_dev_intr_handler, dev);\n+}\n+\n static const uint32_t*\n tap_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused)\n {\n@@ -1117,7 +1175,7 @@ eth_dev_tap_create(const char *name, char *tap_name, char *remote_iface)\n \tdata->dev_private = pmd;\n \tdata->port_id = dev->data->port_id;\n \tdata->mtu = dev->data->mtu;\n-\tdata->dev_flags = RTE_ETH_DEV_DETACHABLE;\n+\tdata->dev_flags = RTE_ETH_DEV_DETACHABLE | RTE_ETH_DEV_INTR_LSC;\n \tdata->kdrv = RTE_KDRV_NONE;\n \tdata->drv_name = pmd_tap_drv.driver.name;\n \tdata->numa_node = numa_node;\n@@ -1133,6 +1191,9 @@ eth_dev_tap_create(const char *name, char *tap_name, char *remote_iface)\n \tdev->rx_pkt_burst = pmd_rx_burst;\n \tdev->tx_pkt_burst = pmd_tx_burst;\n \n+\tpmd->intr_handle.type = RTE_INTR_HANDLE_EXT;\n+\tpmd->intr_handle.fd = -1;\n+\n \t/* Presetup the fds to -1 as being not valid */\n \tfor (i = 0; i < RTE_PMD_TAP_MAX_QUEUES; i++) {\n \t\tpmd->rxq[i].fd = -1;\n@@ -1147,7 +1208,7 @@ eth_dev_tap_create(const char *name, char *tap_name, char *remote_iface)\n \t * If no netlink socket can be created, then it will fail when\n \t * creating/destroying flow rules.\n \t */\n-\tpmd->nlsk_fd = nl_init();\n+\tpmd->nlsk_fd = nl_init(0);\n \tif (strlen(remote_iface)) {\n \t\tpmd->remote_if_index = if_nametoindex(remote_iface);\n \t\tsnprintf(pmd->remote_iface, RTE_ETH_NAME_MAX_LEN,\ndiff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h\nindex a559f6b0a3b0..f1496dcfdb1a 100644\n--- a/drivers/net/tap/rte_eth_tap.h\n+++ b/drivers/net/tap/rte_eth_tap.h\n@@ -90,6 +90,7 @@ struct pmd_internals {\n \tLIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;\n \tstruct rx_queue rxq[RTE_PMD_TAP_MAX_QUEUES]; /* List of RX queues */\n \tstruct tx_queue txq[RTE_PMD_TAP_MAX_QUEUES]; /* List of TX queues */\n+\tstruct rte_intr_handle intr_handle;          /* LSC interrupt handle. */\n };\n \n #endif /* _RTE_ETH_TAP_H_ */\ndiff --git a/drivers/net/tap/tap_netlink.c b/drivers/net/tap/tap_netlink.c\nindex 9710e41a7801..6de896ab17b6 100644\n--- a/drivers/net/tap/tap_netlink.c\n+++ b/drivers/net/tap/tap_netlink.c\n@@ -55,14 +55,21 @@ struct nested_tail {\n /**\n  * Initialize a netlink socket for communicating with the kernel.\n  *\n+ * @param nl_groups\n+ *   Set it to a netlink group value (e.g. RTMGRP_LINK) to receive messages for\n+ *   specific netlink multicast groups. Otherwise, no subscription will be made.\n+ *\n  * @return\n  *   netlink socket file descriptor on success, -1 otherwise.\n  */\n int\n-nl_init(void)\n+nl_init(uint32_t nl_groups)\n {\n \tint fd, sndbuf_size = SNDBUF_SIZE, rcvbuf_size = RCVBUF_SIZE;\n-\tstruct sockaddr_nl local = { .nl_family = AF_NETLINK };\n+\tstruct sockaddr_nl local = {\n+\t\t.nl_family = AF_NETLINK,\n+\t\t.nl_groups = nl_groups,\n+\t};\n \n \tfd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);\n \tif (fd < 0) {\ndiff --git a/drivers/net/tap/tap_netlink.h b/drivers/net/tap/tap_netlink.h\nindex 52ba8c030dcc..98e1390268d8 100644\n--- a/drivers/net/tap/tap_netlink.h\n+++ b/drivers/net/tap/tap_netlink.h\n@@ -53,7 +53,7 @@ struct nlmsg {\n \n #define NLMSG_TAIL(nlh) (void *)((char *)(nlh) + NLMSG_ALIGN((nlh)->nlmsg_len))\n \n-int nl_init(void);\n+int nl_init(uint32_t nl_groups);\n int nl_final(int nlsk_fd);\n int nl_send(int nlsk_fd, struct nlmsghdr *nh);\n int nl_recv(int nlsk_fd, int (*callback)(struct nlmsghdr *, void *), void *arg);\ndiff --git a/drivers/net/tap/tap_tcmsgs.c b/drivers/net/tap/tap_tcmsgs.c\nindex 9a146d165b08..af1c9aec0d22 100644\n--- a/drivers/net/tap/tap_tcmsgs.c\n+++ b/drivers/net/tap/tap_tcmsgs.c\n@@ -107,7 +107,7 @@ qdisc_del(int nlsk_fd, uint16_t ifindex, struct qdisc *qinfo)\n \tmsg.t.tcm_parent = qinfo->parent;\n \t/* if no netlink socket is provided, create one */\n \tif (!nlsk_fd) {\n-\t\tfd = nl_init();\n+\t\tfd = nl_init(0);\n \t\tif (fd < 0) {\n \t\t\tRTE_LOG(ERR, PMD,\n \t\t\t\t\"Could not delete QDISC: null netlink socket\\n\");\n",
    "prefixes": [
        "dpdk-dev",
        "2/2"
    ]
}