get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 810834,
    "url": "http://patchwork.ozlabs.org/api/patches/810834/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/1504744467-79590-4-git-send-email-sainath.grandhi@intel.com/",
    "project": {
        "id": 7,
        "url": "http://patchwork.ozlabs.org/api/projects/7/?format=api",
        "name": "Linux network development",
        "link_name": "netdev",
        "list_id": "netdev.vger.kernel.org",
        "list_email": "netdev@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1504744467-79590-4-git-send-email-sainath.grandhi@intel.com>",
    "list_archive_url": null,
    "date": "2017-09-07T00:34:27",
    "name": "[RFC,v1,3/3] vethtap: veth based tap driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "rfc",
    "archived": true,
    "hash": "194fb660743fc15fae1e5fa67e5ed020a1e6446e",
    "submitter": {
        "id": 70733,
        "url": "http://patchwork.ozlabs.org/api/people/70733/?format=api",
        "name": "Grandhi, Sainath",
        "email": "sainath.grandhi@intel.com"
    },
    "delegate": {
        "id": 34,
        "url": "http://patchwork.ozlabs.org/api/users/34/?format=api",
        "username": "davem",
        "first_name": "David",
        "last_name": "Miller",
        "email": "davem@davemloft.net"
    },
    "mbox": "http://patchwork.ozlabs.org/project/netdev/patch/1504744467-79590-4-git-send-email-sainath.grandhi@intel.com/mbox/",
    "series": [
        {
            "id": 1899,
            "url": "http://patchwork.ozlabs.org/api/series/1899/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/netdev/list/?series=1899",
            "date": "2017-09-07T00:34:24",
            "name": "Support for tap user-space access with veth interfaces",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/1899/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/810834/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/810834/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<netdev-owner@vger.kernel.org>",
        "X-Original-To": "patchwork-incoming@ozlabs.org",
        "Delivered-To": "patchwork-incoming@ozlabs.org",
        "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=netdev-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)",
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xnhPr21NRz9s8J\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu,  7 Sep 2017 10:38:08 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1753025AbdIGAiG (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tWed, 6 Sep 2017 20:38:06 -0400",
            "from mga03.intel.com ([134.134.136.65]:16007 \"EHLO mga03.intel.com\"\n\trhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP\n\tid S1752063AbdIGAiF (ORCPT <rfc822;netdev@vger.kernel.org>);\n\tWed, 6 Sep 2017 20:38:05 -0400",
            "from fmsmga002.fm.intel.com ([10.253.24.26])\n\tby orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t06 Sep 2017 17:38:04 -0700",
            "from otc-grantley-03.jf.intel.com ([10.54.39.23])\n\tby fmsmga002.fm.intel.com with ESMTP; 06 Sep 2017 17:38:04 -0700"
        ],
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.42,355,1500966000\"; d=\"scan'208\";a=\"1215697678\"",
        "From": "sainath.grandhi@intel.com",
        "To": "netdev@vger.kernel.org",
        "Cc": "davem@davemloft.net, Sainath Grandhi <sainath.grandhi@intel.com>",
        "Subject": "[PATCH RFC v1 3/3] vethtap: veth based tap driver",
        "Date": "Wed,  6 Sep 2017 17:34:27 -0700",
        "Message-Id": "<1504744467-79590-4-git-send-email-sainath.grandhi@intel.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-Reply-To": "<1504744467-79590-1-git-send-email-sainath.grandhi@intel.com>",
        "References": "<1504744467-79590-1-git-send-email-sainath.grandhi@intel.com>",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "From: Sainath Grandhi <sainath.grandhi@intel.com>\n\nThis patch adds a tap character device driver that is based on the\nveth network interface, called vethtap. This patchset allows vethtap device\nto be created ONLY as a peer interface to a veth network interface. It can\nbe created in the following way,\nip link add veth1 type veth peer name veth2 type vethtap\nWith this packets on veth2 can be accessed using tap user space interface.\n\nSigned-off-by: Sainath Grandhi <sainath.grandhi@intel.com>\n---\n drivers/net/Kconfig                 |   1 +\n drivers/net/Makefile                |   2 +\n drivers/net/{veth.c => veth_main.c} |  33 +++++-\n drivers/net/vethtap.c               | 216 ++++++++++++++++++++++++++++++++++++\n include/linux/if_veth.h             |   4 +\n 5 files changed, 255 insertions(+), 1 deletion(-)\n rename drivers/net/{veth.c => veth_main.c} (94%)\n create mode 100644 drivers/net/vethtap.c",
    "diff": "diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig\nindex aba0d65..265853e 100644\n--- a/drivers/net/Kconfig\n+++ b/drivers/net/Kconfig\n@@ -323,6 +323,7 @@ config TUN_VNET_CROSS_LE\n \n config VETH\n \ttristate \"Virtual ethernet pair device\"\n+\tselect TAP\n \t---help---\n \t  This device is a local ethernet tunnel. Devices are created in pairs.\n \t  When one end receives the packet it appears on its pair and vice\ndiff --git a/drivers/net/Makefile b/drivers/net/Makefile\nindex 8dff900..7c63e69 100644\n--- a/drivers/net/Makefile\n+++ b/drivers/net/Makefile\n@@ -32,6 +32,8 @@ obj-$(CONFIG_NLMON) += nlmon.o\n obj-$(CONFIG_NET_VRF) += vrf.o\n obj-$(CONFIG_VSOCKMON) += vsockmon.o\n \n+veth-objs := veth_main.o vethtap.o\n+\n #\n # Networking Drivers\n #\ndiff --git a/drivers/net/veth.c b/drivers/net/veth_main.c\nsimilarity index 94%\nrename from drivers/net/veth.c\nrename to drivers/net/veth_main.c\nindex a1b370d..fc91dd7 100644\n--- a/drivers/net/veth.c\n+++ b/drivers/net/veth_main.c\n@@ -359,6 +359,9 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,\n \tunsigned char name_assign_type;\n \tstruct ifinfomsg *ifmp;\n \tstruct net *net;\n+\tstruct nlattr *linkinfo[IFLA_INFO_MAX + 1];\n+\tchar peer_type[8];\n+\tstruct rtnl_link_ops *link_ops;\n \n \t/*\n \t * create and register peer first\n@@ -393,17 +396,38 @@ static int veth_newlink(struct net *src_net, struct net_device *dev,\n \t\tname_assign_type = NET_NAME_ENUM;\n \t}\n \n+\tlink_ops = &veth_link_ops;\n+\tif (tbp[IFLA_LINKINFO]) {\n+\t\terr = rtnl_nla_parse_ifla_info(linkinfo,\n+\t\t\t\t\t       nla_data(tbp[IFLA_LINKINFO]),\n+\t\t\t\t\t       nla_len(tbp[IFLA_LINKINFO]),\n+\t\t\t\t\t       NULL);\n+\n+\t\tif (err < 0)\n+\t\t\treturn err;\n+\n+\t\tif (linkinfo[IFLA_INFO_KIND]) {\n+\t\t\tnla_strlcpy(peer_type, linkinfo[IFLA_INFO_KIND],\n+\t\t\t\t    sizeof(peer_type));\n+\t\t\tif (!strncmp(peer_type, \"vethtap\", sizeof(peer_type)))\n+\t\t\t\tlink_ops = &vethtap_link_ops;\n+\t\t}\n+\t}\n+\n \tnet = rtnl_link_get_net(src_net, tbp);\n \tif (IS_ERR(net))\n \t\treturn PTR_ERR(net);\n \n \tpeer = rtnl_create_link(net, ifname, name_assign_type,\n-\t\t\t\t&veth_link_ops, tbp);\n+\t\t\t\tlink_ops, tbp);\n \tif (IS_ERR(peer)) {\n \t\tput_net(net);\n \t\treturn PTR_ERR(peer);\n \t}\n \n+\tif (!strncmp(peer_type, \"vethtap\", sizeof(peer_type)))\n+\t\tlink_ops->newlink(net, peer, tbp, NULL, NULL);\n+\n \tif (!ifmp || !tbp[IFLA_ADDRESS])\n \t\teth_hw_addr_random(peer);\n \n@@ -536,12 +560,19 @@ static __init int veth_init(void)\n \n \terr = veth_link_register(&veth_link_ops);\n \n+\tif (err)\n+\t\tgoto out1;\n+\n+\terr = vethtap_init();\n+\n+out1:\n \treturn err;\n }\n \n static __exit void veth_exit(void)\n {\n \trtnl_link_unregister(&veth_link_ops);\n+\tvethtap_exit();\n }\n \n module_init(veth_init);\ndiff --git a/drivers/net/vethtap.c b/drivers/net/vethtap.c\nnew file mode 100644\nindex 0000000..922b3ea\n--- /dev/null\n+++ b/drivers/net/vethtap.c\n@@ -0,0 +1,216 @@\n+#include <linux/etherdevice.h>\n+#include <linux/if_tap.h>\n+#include <linux/if_vlan.h>\n+#include <linux/if_veth.h>\n+#include <linux/interrupt.h>\n+#include <linux/nsproxy.h>\n+#include <linux/compat.h>\n+#include <linux/if_tun.h>\n+#include <linux/module.h>\n+#include <linux/skbuff.h>\n+#include <linux/cache.h>\n+#include <linux/sched/signal.h>\n+#include <linux/types.h>\n+#include <linux/slab.h>\n+#include <linux/wait.h>\n+#include <linux/cdev.h>\n+#include <linux/idr.h>\n+#include <linux/fs.h>\n+#include <linux/uio.h>\n+\n+#include <net/net_namespace.h>\n+#include <net/rtnetlink.h>\n+#include <net/sock.h>\n+#include <linux/virtio_net.h>\n+#include <linux/skb_array.h>\n+\n+struct vethtap_dev {\n+\tstruct veth_priv  veth;\n+\tstruct tap_dev    tap;\n+};\n+\n+/* Variables for dealing with vethtaps device numbers.\n+ */\n+static dev_t vethtap_major;\n+\n+static const void *vethtap_net_namespace(struct device *d)\n+{\n+\tstruct net_device *dev = to_net_dev(d->parent);\n+\n+\treturn dev_net(dev);\n+}\n+\n+static struct class vethtap_class = {\n+\t.name = \"vethtap\",\n+\t.owner = THIS_MODULE,\n+\t.ns_type = &net_ns_type_operations,\n+\t.namespace = vethtap_net_namespace,\n+};\n+\n+static struct cdev vethtap_cdev;\n+\n+#define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \\\n+\t\t      NETIF_F_TSO6)\n+\n+static void vethtap_count_tx_dropped(struct tap_dev *tap)\n+{\n+\tstruct vethtap_dev *vethtap = container_of(tap, struct vethtap_dev,\n+\t\t\t\t\t\t   tap);\n+\tstruct veth_priv *veth = &vethtap->veth;\n+\n+\tatomic64_inc(&veth->dropped);\n+}\n+\n+static int vethtap_newlink(struct net *src_net, struct net_device *dev,\n+\t\t\t   struct nlattr *tb[], struct nlattr *data[],\n+\t\t\t   struct netlink_ext_ack *extack)\n+{\n+\tstruct vethtap_dev *vethtap = netdev_priv(dev);\n+\tint err;\n+\n+\tINIT_LIST_HEAD(&vethtap->tap.queue_list);\n+\n+\t/* Since macvlan supports all offloads by default, make\n+\t * tap support all offloads also.\n+\t */\n+\tvethtap->tap.tap_features = TUN_OFFLOADS;\n+\n+\t/* Register callbacks for rx/tx drops accounting and updating\n+\t * net_device features\n+\t */\n+\tvethtap->tap.count_tx_dropped = vethtap_count_tx_dropped;\n+\tvethtap->tap.count_rx_dropped = NULL;\n+\tvethtap->tap.update_features  = NULL;\n+\n+\terr = netdev_rx_handler_register(dev, tap_handle_frame, &vethtap->tap);\n+\tif (err)\n+\t\treturn err;\n+\n+\tvethtap->tap.dev = dev;\n+\n+\treturn 0;\n+}\n+\n+static void vethtap_dellink(struct net_device *dev,\n+\t\t\t    struct list_head *head)\n+{\n+\tstruct vethtap_dev *vethtap = netdev_priv(dev);\n+\n+\tnetdev_rx_handler_unregister(dev);\n+\ttap_del_queues(&vethtap->tap);\n+\tveth_dellink(dev, head);\n+}\n+\n+static void vethtap_setup(struct net_device *dev)\n+{\n+\tveth_common_setup(dev);\n+\tdev->tx_queue_len = TUN_READQ_SIZE;\n+}\n+\n+struct rtnl_link_ops vethtap_link_ops __read_mostly = {\n+\t.kind           = \"vethtap\",\n+\t.setup\t\t= vethtap_setup,\n+\t.newlink\t= vethtap_newlink,\n+\t.dellink\t= vethtap_dellink,\n+\t.priv_size      = sizeof(struct vethtap_dev),\n+};\n+\n+static int vethtap_device_event(struct notifier_block *unused,\n+\t\t\t\tunsigned long event, void *ptr)\n+{\n+\tstruct net_device *dev = netdev_notifier_info_to_dev(ptr);\n+\tstruct vethtap_dev *vethtap;\n+\tstruct device *classdev;\n+\tdev_t devt;\n+\tint err;\n+\tchar tap_name[IFNAMSIZ];\n+\n+\tif (dev->rtnl_link_ops != &vethtap_link_ops)\n+\t\treturn NOTIFY_DONE;\n+\n+\tsnprintf(tap_name, IFNAMSIZ, \"tap%d\", dev->ifindex);\n+\tvethtap = netdev_priv(dev);\n+\n+\tswitch (event) {\n+\tcase NETDEV_REGISTER:\n+\t\t/* Create the device node here after the network device has\n+\t\t * been registered but before register_netdevice has\n+\t\t * finished running.\n+\t\t */\n+\t\terr = tap_get_minor(vethtap_major, &vethtap->tap);\n+\t\tif (err)\n+\t\t\treturn notifier_from_errno(err);\n+\n+\t\tdevt = MKDEV(MAJOR(vethtap_major), vethtap->tap.minor);\n+\t\tclassdev = device_create(&vethtap_class, &dev->dev, devt,\n+\t\t\t\t\t dev, tap_name);\n+\t\tif (IS_ERR(classdev)) {\n+\t\t\ttap_free_minor(vethtap_major, &vethtap->tap);\n+\t\t\treturn notifier_from_errno(PTR_ERR(classdev));\n+\t\t}\n+\t\terr = sysfs_create_link(&dev->dev.kobj, &classdev->kobj,\n+\t\t\t\t\ttap_name);\n+\t\tif (err)\n+\t\t\treturn notifier_from_errno(err);\n+\t\tbreak;\n+\tcase NETDEV_UNREGISTER:\n+\t\t/* vlan->minor == 0 if NETDEV_REGISTER above failed */\n+\t\tif (vethtap->tap.minor == 0)\n+\t\t\tbreak;\n+\t\tsysfs_remove_link(&dev->dev.kobj, tap_name);\n+\t\tdevt = MKDEV(MAJOR(vethtap_major), vethtap->tap.minor);\n+\t\tdevice_destroy(&vethtap_class, devt);\n+\t\ttap_free_minor(vethtap_major, &vethtap->tap);\n+\t\tbreak;\n+\tcase NETDEV_CHANGE_TX_QUEUE_LEN:\n+\t\tif (tap_queue_resize(&vethtap->tap))\n+\t\t\treturn NOTIFY_BAD;\n+\t\tbreak;\n+\t}\n+\n+\treturn NOTIFY_DONE;\n+}\n+\n+static struct notifier_block vethtap_notifier_block __read_mostly = {\n+\t.notifier_call\t= vethtap_device_event,\n+};\n+\n+int vethtap_init(void)\n+{\n+\tint err;\n+\n+\terr = tap_create_cdev(&vethtap_cdev, &vethtap_major, \"vethtap\");\n+\n+\tif (err)\n+\t\tgoto out1;\n+\n+\terr = class_register(&vethtap_class);\n+\tif (err)\n+\t\tgoto out2;\n+\n+\terr = register_netdevice_notifier(&vethtap_notifier_block);\n+\tif (err)\n+\t\tgoto out3;\n+\n+\tveth_link_ops_init(&vethtap_link_ops);\n+\tif (err)\n+\t\tgoto out4;\n+\n+\treturn 0;\n+\n+out4:\n+\tunregister_netdevice_notifier(&vethtap_notifier_block);\n+out3:\n+\tclass_unregister(&vethtap_class);\n+out2:\n+\ttap_destroy_cdev(vethtap_major, &vethtap_cdev);\n+out1:\n+\treturn err;\n+}\n+\n+void vethtap_exit(void)\n+{\n+\tunregister_netdevice_notifier(&vethtap_notifier_block);\n+\tclass_unregister(&vethtap_class);\n+\ttap_destroy_cdev(vethtap_major, &vethtap_cdev);\n+}\ndiff --git a/include/linux/if_veth.h b/include/linux/if_veth.h\nindex b007891..dbc06c4 100644\n--- a/include/linux/if_veth.h\n+++ b/include/linux/if_veth.h\n@@ -4,6 +4,10 @@ struct veth_priv {\n \tunsigned int            requested_headroom;\n };\n \n+extern struct rtnl_link_ops vethtap_link_ops;\n+\n void veth_common_setup(struct net_device *dev);\n void veth_dellink(struct net_device *dev, struct list_head *head);\n void veth_link_ops_init(struct rtnl_link_ops *ops);\n+int vethtap_init(void);\n+void vethtap_exit(void);\n",
    "prefixes": [
        "RFC",
        "v1",
        "3/3"
    ]
}