get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 890,
    "url": "http://patchwork.ozlabs.org/api/patches/890/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/netdev/patch/1222098445-26175-10-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-10-git-send-email-remi.denis-courmont@nokia.com>",
    "list_archive_url": null,
    "date": "2008-09-22T15:47:24",
    "name": "[10/11] Phonet: emit errors when a packet cannot be delivered locally",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "098929faf2cc0fdbfbe46a71b0a1f3f5df707b23",
    "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-10-git-send-email-remi.denis-courmont@nokia.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/890/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/890/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 333F6DDF58\n\tfor <patchwork-incoming@ozlabs.org>;\n\tTue, 23 Sep 2008 01:48:35 +1000 (EST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752776AbYIVPsD (ORCPT <rfc822;patchwork-incoming@ozlabs.org>);\n\tMon, 22 Sep 2008 11:48:03 -0400",
            "(majordomo@vger.kernel.org) by vger.kernel.org id S1752884AbYIVPsA\n\t(ORCPT <rfc822; netdev-outgoing>); Mon, 22 Sep 2008 11:48:00 -0400",
            "from smtp.nokia.com ([192.100.105.134]:34635 \"EHLO\n\tmgw-mx09.nokia.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1753646AbYIVPru (ORCPT\n\t<rfc822;netdev@vger.kernel.org>); Mon, 22 Sep 2008 11:47:50 -0400",
            "from vaebh105.NOE.Nokia.com (vaebh105.europe.nokia.com\n\t[10.160.244.31])\n\tby mgw-mx09.nokia.com (Switch-3.2.6/Switch-3.2.6) with ESMTP id\n\tm8MFlIhh008928\n\tfor <netdev@vger.kernel.org>; Mon, 22 Sep 2008 10:47:48 -0500",
            "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 10/11] Phonet: emit errors when a packet cannot be delivered\n\tlocally",
        "Date": "Mon, 22 Sep 2008 18:47:24 +0300",
        "Message-Id": "<1222098445-26175-10-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.0803 (UTC)\n\tFILETIME=[83444230: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": "When there is no listener socket for a received packet, send an error\nback to the sender.\n\nSigned-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>\n---\n include/linux/phonet.h      |   32 ++++++++++++++\n include/net/phonet/phonet.h |    5 ++\n net/phonet/af_phonet.c      |   96 +++++++++++++++++++++++++++++++++++++++++--\n 3 files changed, 129 insertions(+), 4 deletions(-)",
    "diff": "diff --git a/include/linux/phonet.h b/include/linux/phonet.h\nindex 001c0e6..3a027f5 100644\n--- a/include/linux/phonet.h\n+++ b/include/linux/phonet.h\n@@ -45,6 +45,38 @@ struct phonethdr {\n \t__u8\tpn_sobj;\n } __attribute__((packed));\n \n+/* Common Phonet payload header */\n+struct phonetmsg {\n+\t__u8\tpn_trans_id;\t/* transaction ID */\n+\t__u8\tpn_msg_id;\t/* message type */\n+\tunion {\n+\t\tstruct {\n+\t\t\t__u8\tpn_submsg_id;\t/* message subtype */\n+\t\t\t__u8\tpn_data[5];\n+\t\t} base;\n+\t\tstruct {\n+\t\t\t__u16\tpn_e_res_id;\t/* extended resource ID */\n+\t\t\t__u8\tpn_e_submsg_id;\t/* message subtype */\n+\t\t\t__u8\tpn_e_data[3];\n+\t\t} ext;\n+\t} pn_msg_u;\n+};\n+#define PN_COMMON_MESSAGE\t0xF0\n+#define PN_PREFIX\t\t0xE0 /* resource for extended messages */\n+#define pn_submsg_id\t\tpn_msg_u.base.pn_submsg_id\n+#define pn_e_submsg_id\t\tpn_msg_u.ext.pn_e_submsg_id\n+#define pn_e_res_id\t\tpn_msg_u.ext.pn_e_res_id\n+#define pn_data\t\t\tpn_msg_u.base.pn_data\n+#define pn_e_data\t\tpn_msg_u.ext.pn_e_data\n+\n+/* data for unreachable errors */\n+#define PN_COMM_SERVICE_NOT_IDENTIFIED_RESP\t0x01\n+#define PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP\t0x14\n+#define pn_orig_msg_id\t\tpn_data[0]\n+#define pn_status\t\tpn_data[1]\n+#define pn_e_orig_msg_id\tpn_e_data[0]\n+#define pn_e_status\t\tpn_e_data[1]\n+\n /* Phonet socket address structure */\n struct sockaddr_pn {\n \tsa_family_t spn_family;\ndiff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h\nindex 1c6f7e7..d4e7250 100644\n--- a/include/net/phonet/phonet.h\n+++ b/include/net/phonet/phonet.h\n@@ -60,6 +60,11 @@ static inline struct phonethdr *pn_hdr(struct sk_buff *skb)\n \treturn (struct phonethdr *)skb_network_header(skb);\n }\n \n+static inline struct phonetmsg *pn_msg(struct sk_buff *skb)\n+{\n+\treturn (struct phonetmsg *)skb_transport_header(skb);\n+}\n+\n /*\n  * Get the other party's sockaddr from received skb. The skb begins\n  * with a Phonet header.\ndiff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c\nindex 50dc258..1d8df6b 100644\n--- a/net/phonet/af_phonet.c\n+++ b/net/phonet/af_phonet.c\n@@ -132,7 +132,7 @@ EXPORT_SYMBOL(phonet_header_ops);\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+\t\t\tu16 dst, u16 src, u8 res, u8 irq)\n {\n \tstruct phonethdr *ph;\n \tint err;\n@@ -163,7 +163,10 @@ static int pn_send(struct sk_buff *skb, struct net_device *dev,\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\tif (irq)\n+\t\t\tnetif_rx(skb);\n+\t\telse\n+\t\t\tnetif_rx_ni(skb);\n \t\terr = 0;\n \t} else {\n \t\terr = dev_hard_header(skb, dev, ntohs(skb->protocol),\n@@ -181,6 +184,19 @@ drop:\n \treturn err;\n }\n \n+static int pn_raw_send(const void *data, int len, struct net_device *dev,\n+\t\t\tu16 dst, u16 src, u8 res)\n+{\n+\tstruct sk_buff *skb = alloc_skb(MAX_PHONET_HEADER + len, GFP_ATOMIC);\n+\tif (skb == NULL)\n+\t\treturn -ENOMEM;\n+\n+\tskb_reserve(skb, MAX_PHONET_HEADER);\n+\t__skb_put(skb, len);\n+\tskb_copy_to_linear_data(skb, data, len);\n+\treturn pn_send(skb, dev, dst, src, res, 1);\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@@ -211,7 +227,7 @@ int pn_skb_send(struct sock *sk, struct sk_buff *skb,\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+\t\t\tsrc, pn_sockaddr_get_resource(target), 0);\n \tdev_put(dev);\n \treturn err;\n \n@@ -223,6 +239,73 @@ drop:\n }\n EXPORT_SYMBOL(pn_skb_send);\n \n+/* Do not send an error message in response to an error message */\n+static inline int can_respond(struct sk_buff *skb)\n+{\n+\tconst struct phonethdr *ph;\n+\tconst struct phonetmsg *pm;\n+\tu8 submsg_id;\n+\n+\tif (!pskb_may_pull(skb, 3))\n+\t\treturn 0;\n+\n+\tph = pn_hdr(skb);\n+\tif (phonet_address_get(skb->dev, ph->pn_rdev) != ph->pn_rdev)\n+\t\treturn 0; /* we are not the destination */\n+\tif (ph->pn_res == PN_PREFIX && !pskb_may_pull(skb, 5))\n+\t\treturn 0;\n+\n+\tph = pn_hdr(skb); /* re-acquires the pointer */\n+\tpm = pn_msg(skb);\n+\tif (pm->pn_msg_id != PN_COMMON_MESSAGE)\n+\t\treturn 1;\n+\tsubmsg_id = (ph->pn_res == PN_PREFIX)\n+\t\t? pm->pn_e_submsg_id : pm->pn_submsg_id;\n+\tif (submsg_id != PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP &&\n+\t\tpm->pn_e_submsg_id != PN_COMM_SERVICE_NOT_IDENTIFIED_RESP)\n+\t\treturn 1;\n+\treturn 0;\n+}\n+\n+static int send_obj_unreachable(struct sk_buff *rskb)\n+{\n+\tconst struct phonethdr *oph = pn_hdr(rskb);\n+\tconst struct phonetmsg *opm = pn_msg(rskb);\n+\tstruct phonetmsg resp;\n+\n+\tmemset(&resp, 0, sizeof(resp));\n+\tresp.pn_trans_id = opm->pn_trans_id;\n+\tresp.pn_msg_id = PN_COMMON_MESSAGE;\n+\tif (oph->pn_res == PN_PREFIX) {\n+\t\tresp.pn_e_res_id = opm->pn_e_res_id;\n+\t\tresp.pn_e_submsg_id = PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP;\n+\t\tresp.pn_e_orig_msg_id = opm->pn_msg_id;\n+\t\tresp.pn_e_status = 0;\n+\t} else {\n+\t\tresp.pn_submsg_id = PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP;\n+\t\tresp.pn_orig_msg_id = opm->pn_msg_id;\n+\t\tresp.pn_status = 0;\n+\t}\n+\treturn pn_raw_send(&resp, sizeof(resp), rskb->dev,\n+\t\t\t\tpn_object(oph->pn_sdev, oph->pn_sobj),\n+\t\t\t\tpn_object(oph->pn_rdev, oph->pn_robj),\n+\t\t\t\toph->pn_res);\n+}\n+\n+static int send_reset_indications(struct sk_buff *rskb)\n+{\n+\tstruct phonethdr *oph = pn_hdr(rskb);\n+\tstatic const u8 data[4] = {\n+\t\t0x00 /* trans ID */, 0x10 /* subscribe msg */,\n+\t\t0x00 /* subscription count */, 0x00 /* dummy */\n+\t};\n+\n+\treturn pn_raw_send(data, sizeof(data), rskb->dev,\n+\t\t\t\tpn_object(oph->pn_sdev, 0x00),\n+\t\t\t\tpn_object(oph->pn_rdev, oph->pn_robj), 0x10);\n+}\n+\n+\n /* packet type functions */\n \n /*\n@@ -260,8 +343,13 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,\n \t\tgoto out; /* currently, we cannot be device 0 */\n \n \tsk = pn_find_sock_by_sa(&sa);\n-\tif (sk == NULL)\n+\tif (sk == NULL) {\n+\t\tif (can_respond(skb)) {\n+\t\t\tsend_obj_unreachable(skb);\n+\t\t\tsend_reset_indications(skb);\n+\t\t}\n \t\tgoto out;\n+\t}\n \n \t/* Push data to the socket (or other sockets connected to it). */\n \treturn sk_receive_skb(sk, skb, 0);\n",
    "prefixes": [
        "10/11"
    ]
}