get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 888,
    "url": "http://patchwork.ozlabs.org/api/patches/888/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/1222098445-26175-7-git-send-email-remi.denis-courmont@nokia.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": "<1222098445-26175-7-git-send-email-remi.denis-courmont@nokia.com>",
    "list_archive_url": null,
    "date": "2008-09-22T15:47:21",
    "name": "[07/11] Phonet: Phonet datagram transport protocol",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "64a6994af2a62204380734ccd7de1a4e303264ac",
    "submitter": {
        "id": 204,
        "url": "http://patchwork.ozlabs.org/api/people/204/?format=api",
        "name": "Rémi Denis-Courmont",
        "email": "remi.denis-courmont@nokia.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/1222098445-26175-7-git-send-email-remi.denis-courmont@nokia.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/888/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/888/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<netdev-owner@vger.kernel.org>",
        "X-Original-To": "patchwork-incoming@ozlabs.org",
        "Delivered-To": "patchwork-incoming@ozlabs.org",
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.176.167])\n\tby ozlabs.org (Postfix) with ESMTP id 998D9DDF58\n\tfor <patchwork-incoming@ozlabs.org>;\n\tTue, 23 Sep 2008 01:48:33 +1000 (EST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1753858AbYIVPr4 (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 22 Sep 2008 11:47:56 -0400",
            "(majordomo@vger.kernel.org) by vger.kernel.org id S1752662AbYIVPrz\n\t(ORCPT <rfc822; netdev-outgoing>); Mon, 22 Sep 2008 11:47:55 -0400",
            "from smtp.nokia.com ([192.100.122.233]:53017 \"EHLO\n\tmgw-mx06.nokia.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1753666AbYIVPrv (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Mon, 22 Sep 2008 11:47:51 -0400",
            "from vaebh105.NOE.Nokia.com (vaebh105.europe.nokia.com\n\t[10.160.244.31])\n\tby mgw-mx06.nokia.com (Switch-3.2.6/Switch-3.2.6) with ESMTP id\n\tm8MFlZFl027641\n\tfor <netdev@vger.kernel.org>; Mon, 22 Sep 2008 18:47:48 +0300",
            "from vaebh102.NOE.Nokia.com ([10.160.244.23]) by\n\tvaebh105.NOE.Nokia.com with Microsoft SMTPSVC(6.0.3790.3959); \n\tMon, 22 Sep 2008 18:47:45 +0300",
            "from localhost.localdomain ([172.21.41.115]) by\n\tvaebh102.NOE.Nokia.com with Microsoft SMTPSVC(6.0.3790.3959); \n\tMon, 22 Sep 2008 18:47:26 +0300"
        ],
        "From": "=?utf-8?q?R=C3=A9mi=20Denis-Courmont?= <remi.denis-courmont@nokia.com>",
        "To": "netdev@vger.kernel.org",
        "Subject": "[PATCH 07/11] Phonet: Phonet datagram transport protocol",
        "Date": "Mon, 22 Sep 2008 18:47:21 +0300",
        "Message-Id": "<1222098445-26175-7-git-send-email-remi.denis-courmont@nokia.com>",
        "X-Mailer": "git-send-email 1.5.4.3",
        "In-Reply-To": "<200809221845.54736.remi.denis-courmont@nokia.com>",
        "References": "<200809221845.54736.remi.denis-courmont@nokia.com>",
        "X-OriginalArrivalTime": "22 Sep 2008 15:47:26.0694 (UTC)\n\tFILETIME=[8333A060:01C91CCA]",
        "X-Nokia-AV": "Clean",
        "Sender": "netdev-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<netdev.vger.kernel.org>",
        "X-Mailing-List": "netdev@vger.kernel.org"
    },
    "content": "This provides the basic SOCK_DGRAM transport protocol for Phonet.\n\nSigned-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>\n---\n include/net/phonet/phonet.h |    6 ++\n net/phonet/Makefile         |    1 +\n net/phonet/af_phonet.c      |  106 +++++++++++++++++++++++\n net/phonet/datagram.c       |  197 +++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 310 insertions(+), 0 deletions(-)\n create mode 100644 net/phonet/datagram.c",
    "diff": "diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h\nindex 2ae5cbb..d3957d3 100644\n--- a/include/net/phonet/phonet.h\n+++ b/include/net/phonet/phonet.h\n@@ -51,6 +51,9 @@ void pn_sock_hash(struct sock *sk);\n void pn_sock_unhash(struct sock *sk);\n int pn_sock_get_port(struct sock *sk, unsigned short sport);\n \n+int pn_skb_send(struct sock *sk, struct sk_buff *skb,\n+\t\tconst struct sockaddr_pn *target);\n+\n static inline struct phonethdr *pn_hdr(struct sk_buff *skb)\n {\n \treturn (struct phonethdr *)skb_network_header(skb);\n@@ -95,4 +98,7 @@ int phonet_proto_register(int protocol, struct phonet_protocol *pp);\n void phonet_proto_unregister(int protocol, struct phonet_protocol *pp);\n \n void phonet_netlink_register(void);\n+int isi_register(void);\n+void isi_unregister(void);\n+\n #endif\ndiff --git a/net/phonet/Makefile b/net/phonet/Makefile\nindex c1d671d..d218abc 100644\n--- a/net/phonet/Makefile\n+++ b/net/phonet/Makefile\n@@ -4,4 +4,5 @@ phonet-objs := \\\n \tpn_dev.o \\\n \tpn_netlink.o \\\n \tsocket.o \\\n+\tdatagram.o \\\n \taf_phonet.o\ndiff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c\nindex ba54d53..e6771d3 100644\n--- a/net/phonet/af_phonet.c\n+++ b/net/phonet/af_phonet.c\n@@ -99,6 +99,101 @@ static struct net_proto_family phonet_proto_family = {\n \t.owner = THIS_MODULE,\n };\n \n+/*\n+ * Prepends an ISI header and sends a datagram.\n+ */\n+static int pn_send(struct sk_buff *skb, struct net_device *dev,\n+\t\t\tu16 dst, u16 src, u8 res)\n+{\n+\tstruct phonethdr *ph;\n+\tint err;\n+\n+\tif (skb->len + 2 > 0xffff) {\n+\t\t/* Phonet length field would overflow */\n+\t\terr = -EMSGSIZE;\n+\t\tgoto drop;\n+\t}\n+\n+\tskb_reset_transport_header(skb);\n+\tWARN_ON(skb_headroom(skb) & 1); /* HW assumes word alignment */\n+\tskb_push(skb, sizeof(struct phonethdr));\n+\tskb_reset_network_header(skb);\n+\tph = pn_hdr(skb);\n+\tph->pn_rdev = pn_dev(dst);\n+\tph->pn_sdev = pn_dev(src);\n+\tph->pn_res = res;\n+\tph->pn_length = __cpu_to_be16(skb->len + 2 - sizeof(*ph));\n+\tph->pn_robj = pn_obj(dst);\n+\tph->pn_sobj = pn_obj(src);\n+\n+\tskb->protocol = htons(ETH_P_PHONET);\n+\tskb->priority = 0;\n+\tskb->dev = dev;\n+\n+\tif (pn_addr(src) == pn_addr(dst)) {\n+\t\tskb_reset_mac_header(skb);\n+\t\tskb->pkt_type = PACKET_LOOPBACK;\n+\t\tskb_orphan(skb);\n+\t\tnetif_rx_ni(skb);\n+\t\terr = 0;\n+\t} else {\n+\t\terr = dev_hard_header(skb, dev, ntohs(skb->protocol),\n+\t\t\t\t\tNULL, NULL, skb->len);\n+\t\tif (err < 0) {\n+\t\t\terr = -EHOSTUNREACH;\n+\t\t\tgoto drop;\n+\t\t}\n+\t\terr = dev_queue_xmit(skb);\n+\t}\n+\n+\treturn err;\n+drop:\n+\tkfree_skb(skb);\n+\treturn err;\n+}\n+\n+/*\n+ * Create a Phonet header for the skb and send it out. Returns\n+ * non-zero error code if failed. The skb is freed then.\n+ */\n+int pn_skb_send(struct sock *sk, struct sk_buff *skb,\n+\t\tconst struct sockaddr_pn *target)\n+{\n+\tstruct net_device *dev;\n+\tstruct pn_sock *pn = pn_sk(sk);\n+\tint err;\n+\tu16 src;\n+\tu8 daddr = pn_sockaddr_get_addr(target), saddr = PN_NO_ADDR;\n+\n+\terr = -EHOSTUNREACH;\n+\tif (sk->sk_bound_dev_if)\n+\t\tdev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if);\n+\telse\n+\t\tdev = phonet_device_get(sock_net(sk));\n+\tif (!dev || !(dev->flags & IFF_UP))\n+\t\tgoto drop;\n+\n+\tsaddr = phonet_address_get(dev, daddr);\n+\tif (saddr == PN_NO_ADDR)\n+\t\tgoto drop;\n+\n+\tsrc = pn->sobject;\n+\tif (!pn_addr(src))\n+\t\tsrc = pn_object(saddr, pn_obj(src));\n+\n+\terr = pn_send(skb, dev, pn_sockaddr_get_object(target),\n+\t\t\tsrc, pn_sockaddr_get_resource(target));\n+\tdev_put(dev);\n+\treturn err;\n+\n+drop:\n+\tkfree_skb(skb);\n+\tif (dev)\n+\t\tdev_put(dev);\n+\treturn err;\n+}\n+EXPORT_SYMBOL(pn_skb_send);\n+\n /* packet type functions */\n \n /*\n@@ -226,11 +321,22 @@ static int __init phonet_init(void)\n \tphonet_device_init();\n \tdev_add_pack(&phonet_packet_type);\n \tphonet_netlink_register();\n+\n+\terr = isi_register();\n+\tif (err)\n+\t\tgoto err;\n \treturn 0;\n+\n+err:\n+\tsock_unregister(AF_PHONET);\n+\tdev_remove_pack(&phonet_packet_type);\n+\tphonet_device_exit();\n+\treturn err;\n }\n \n static void __exit phonet_exit(void)\n {\n+\tisi_unregister();\n \tsock_unregister(AF_PHONET);\n \tdev_remove_pack(&phonet_packet_type);\n \tphonet_device_exit();\ndiff --git a/net/phonet/datagram.c b/net/phonet/datagram.c\nnew file mode 100644\nindex 0000000..e087862\n--- /dev/null\n+++ b/net/phonet/datagram.c\n@@ -0,0 +1,197 @@\n+/*\n+ * File: datagram.c\n+ *\n+ * Datagram (ISI) Phonet sockets\n+ *\n+ * Copyright (C) 2008 Nokia Corporation.\n+ *\n+ * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>\n+ * Original author: Sakari Ailus <sakari.ailus@nokia.com>\n+ *\n+ * This program is free software; you can redistribute it and/or\n+ * modify it under the terms of the GNU General Public License\n+ * version 2 as published by the Free Software Foundation.\n+ *\n+ * This program is distributed in the hope that it will be useful, but\n+ * WITHOUT ANY WARRANTY; without even the implied warranty of\n+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+ * General Public License for more details.\n+ *\n+ * You should have received a copy of the GNU General Public License\n+ * along with this program; if not, write to the Free Software\n+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\n+ * 02110-1301 USA\n+ */\n+\n+#include <linux/kernel.h>\n+#include <linux/socket.h>\n+#include <asm/ioctls.h>\n+#include <net/sock.h>\n+\n+#include <linux/phonet.h>\n+#include <net/phonet/phonet.h>\n+\n+static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb);\n+\n+/* associated socket ceases to exist */\n+static void pn_sock_close(struct sock *sk, long timeout)\n+{\n+\tsk_common_release(sk);\n+}\n+\n+static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg)\n+{\n+\tstruct sk_buff *skb;\n+\tint answ;\n+\n+\tswitch (cmd) {\n+\tcase SIOCINQ:\n+\t\tlock_sock(sk);\n+\t\tskb = skb_peek(&sk->sk_receive_queue);\n+\t\tansw = skb ? skb->len : 0;\n+\t\trelease_sock(sk);\n+\t\treturn put_user(answ, (int __user *)arg);\n+\t}\n+\n+\treturn -ENOIOCTLCMD;\n+}\n+\n+/* Destroy socket. All references are gone. */\n+static void pn_destruct(struct sock *sk)\n+{\n+\tskb_queue_purge(&sk->sk_receive_queue);\n+}\n+\n+static int pn_init(struct sock *sk)\n+{\n+\tsk->sk_destruct = pn_destruct;\n+\treturn 0;\n+}\n+\n+static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,\n+\t\t\tstruct msghdr *msg, size_t len)\n+{\n+\tstruct sockaddr_pn *target;\n+\tstruct sk_buff *skb;\n+\tint err;\n+\n+\tif (msg->msg_flags & MSG_OOB)\n+\t\treturn -EOPNOTSUPP;\n+\n+\tif (msg->msg_name == NULL)\n+\t\treturn -EDESTADDRREQ;\n+\n+\tif (msg->msg_namelen < sizeof(struct sockaddr_pn))\n+\t\treturn -EINVAL;\n+\n+\ttarget = (struct sockaddr_pn *)msg->msg_name;\n+\tif (target->spn_family != AF_PHONET)\n+\t\treturn -EAFNOSUPPORT;\n+\n+\tskb = sock_alloc_send_skb(sk, MAX_PHONET_HEADER + len,\n+\t\t\t\t\tmsg->msg_flags & MSG_DONTWAIT, &err);\n+\tif (skb == NULL)\n+\t\treturn err;\n+\tskb_reserve(skb, MAX_PHONET_HEADER);\n+\n+\terr = memcpy_fromiovec((void *)skb_put(skb, len), msg->msg_iov, len);\n+\tif (err < 0) {\n+\t\tkfree_skb(skb);\n+\t\treturn err;\n+\t}\n+\n+\t/*\n+\t * Fill in the Phonet header and\n+\t * finally pass the packet forwards.\n+\t */\n+\terr = pn_skb_send(sk, skb, target);\n+\n+\t/* If ok, return len. */\n+\treturn (err >= 0) ? len : err;\n+}\n+\n+static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,\n+\t\t\tstruct msghdr *msg, size_t len, int noblock,\n+\t\t\tint flags, int *addr_len)\n+{\n+\tstruct sk_buff *skb = NULL;\n+\tstruct sockaddr_pn sa;\n+\tint rval = -EOPNOTSUPP;\n+\tint copylen;\n+\n+\tif (flags & MSG_OOB)\n+\t\tgoto out_nofree;\n+\n+\tif (addr_len)\n+\t\t*addr_len = sizeof(sa);\n+\n+\tskb = skb_recv_datagram(sk, flags, noblock, &rval);\n+\tif (skb == NULL)\n+\t\tgoto out_nofree;\n+\n+\tpn_skb_get_src_sockaddr(skb, &sa);\n+\n+\tcopylen = skb->len;\n+\tif (len < copylen) {\n+\t\tmsg->msg_flags |= MSG_TRUNC;\n+\t\tcopylen = len;\n+\t}\n+\n+\trval = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copylen);\n+\tif (rval) {\n+\t\trval = -EFAULT;\n+\t\tgoto out;\n+\t}\n+\n+\trval = (flags & MSG_TRUNC) ? skb->len : copylen;\n+\n+\tif (msg->msg_name != NULL)\n+\t\tmemcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn));\n+\n+out:\n+\tskb_free_datagram(sk, skb);\n+\n+out_nofree:\n+\treturn rval;\n+}\n+\n+/* Queue an skb for a sock. */\n+static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb)\n+{\n+\tint err = sock_queue_rcv_skb(sk, skb);\n+\tif (err < 0)\n+\t\tkfree_skb(skb);\n+\treturn err ? NET_RX_DROP : NET_RX_SUCCESS;\n+}\n+\n+/* Module registration */\n+static struct proto pn_proto = {\n+\t.close\t\t= pn_sock_close,\n+\t.ioctl\t\t= pn_ioctl,\n+\t.init\t\t= pn_init,\n+\t.sendmsg\t= pn_sendmsg,\n+\t.recvmsg\t= pn_recvmsg,\n+\t.backlog_rcv\t= pn_backlog_rcv,\n+\t.hash\t\t= pn_sock_hash,\n+\t.unhash\t\t= pn_sock_unhash,\n+\t.get_port\t= pn_sock_get_port,\n+\t.obj_size\t= sizeof(struct pn_sock),\n+\t.owner\t\t= THIS_MODULE,\n+\t.name\t\t= \"PHONET\",\n+};\n+\n+static struct phonet_protocol pn_dgram_proto = {\n+\t.ops\t\t= &phonet_dgram_ops,\n+\t.prot\t\t= &pn_proto,\n+\t.sock_type\t= SOCK_DGRAM,\n+};\n+\n+int __init isi_register(void)\n+{\n+\treturn phonet_proto_register(PN_PROTO_PHONET, &pn_dgram_proto);\n+}\n+\n+void __exit isi_unregister(void)\n+{\n+\tphonet_proto_unregister(PN_PROTO_PHONET, &pn_dgram_proto);\n+}\n",
    "prefixes": [
        "07/11"
    ]
}