get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 809015,
    "url": "http://patchwork.ozlabs.org/api/patches/809015/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20170901012625.14838-5-vinicius.gomes@intel.com/",
    "project": {
        "id": 46,
        "url": "http://patchwork.ozlabs.org/api/projects/46/?format=api",
        "name": "Intel Wired Ethernet development",
        "link_name": "intel-wired-lan",
        "list_id": "intel-wired-lan.osuosl.org",
        "list_email": "intel-wired-lan@osuosl.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170901012625.14838-5-vinicius.gomes@intel.com>",
    "list_archive_url": null,
    "date": "2017-09-01T01:26:24",
    "name": "[RFC,net-next,4/5] sample: Add TSN Talker and Listener examples",
    "commit_ref": null,
    "pull_url": null,
    "state": "rfc",
    "archived": false,
    "hash": "32317dd415a4d442a631a34d4e3d7a1ae4230848",
    "submitter": {
        "id": 72272,
        "url": "http://patchwork.ozlabs.org/api/people/72272/?format=api",
        "name": "Vinicius Costa Gomes",
        "email": "vinicius.gomes@intel.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/intel-wired-lan/patch/20170901012625.14838-5-vinicius.gomes@intel.com/mbox/",
    "series": [
        {
            "id": 1120,
            "url": "http://patchwork.ozlabs.org/api/series/1120/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/intel-wired-lan/list/?series=1120",
            "date": "2017-09-01T01:26:21",
            "name": "TSN: Add qdisc-based config interfaces for traffic shapers",
            "version": 1,
            "mbox": "http://patchwork.ozlabs.org/series/1120/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/809015/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/809015/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<intel-wired-lan-bounces@osuosl.org>",
        "X-Original-To": [
            "incoming@patchwork.ozlabs.org",
            "intel-wired-lan@lists.osuosl.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@bilbo.ozlabs.org",
            "intel-wired-lan@lists.osuosl.org"
        ],
        "Authentication-Results": "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=osuosl.org\n\t(client-ip=140.211.166.136; helo=silver.osuosl.org;\n\tenvelope-from=intel-wired-lan-bounces@osuosl.org;\n\treceiver=<UNKNOWN>)",
        "Received": [
            "from silver.osuosl.org (smtp3.osuosl.org [140.211.166.136])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xkXMD5JxKz9sPm\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat,  2 Sep 2017 07:24:56 +1000 (AEST)",
            "from localhost (localhost [127.0.0.1])\n\tby silver.osuosl.org (Postfix) with ESMTP id E70E530BC8;\n\tFri,  1 Sep 2017 21:24:54 +0000 (UTC)",
            "from silver.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id YFbkFAKN0GC1; Fri,  1 Sep 2017 21:24:50 +0000 (UTC)",
            "from ash.osuosl.org (ash.osuosl.org [140.211.166.34])\n\tby silver.osuosl.org (Postfix) with ESMTP id F09EF30BD0;\n\tFri,  1 Sep 2017 21:24:48 +0000 (UTC)",
            "from hemlock.osuosl.org (smtp2.osuosl.org [140.211.166.133])\n\tby ash.osuosl.org (Postfix) with ESMTP id 827401CEAE4\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri,  1 Sep 2017 01:26:34 +0000 (UTC)",
            "from localhost (localhost [127.0.0.1])\n\tby hemlock.osuosl.org (Postfix) with ESMTP id 7D0E58A115\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri,  1 Sep 2017 01:26:34 +0000 (UTC)",
            "from hemlock.osuosl.org ([127.0.0.1])\n\tby localhost (.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)\n\twith ESMTP id 3gnw5VmfWib0 for <intel-wired-lan@lists.osuosl.org>;\n\tFri,  1 Sep 2017 01:26:32 +0000 (UTC)",
            "from mga01.intel.com (mga01.intel.com [192.55.52.88])\n\tby hemlock.osuosl.org (Postfix) with ESMTPS id A38578A11D\n\tfor <intel-wired-lan@lists.osuosl.org>;\n\tFri,  1 Sep 2017 01:26:32 +0000 (UTC)",
            "from fmsmga006.fm.intel.com ([10.253.24.20])\n\tby fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;\n\t31 Aug 2017 18:26:32 -0700",
            "from ellie.jf.intel.com (HELO localhost.localdomain)\n\t([10.24.8.207])\n\tby fmsmga006.fm.intel.com with ESMTP; 31 Aug 2017 18:26:29 -0700"
        ],
        "X-Virus-Scanned": [
            "amavisd-new at osuosl.org",
            "amavisd-new at osuosl.org"
        ],
        "X-Greylist": "domain auto-whitelisted by SQLgrey-1.7.6",
        "X-ExtLoop1": "1",
        "X-IronPort-AV": "E=Sophos;i=\"5.41,456,1498546800\"; d=\"scan'208\";a=\"146934284\"",
        "From": "Vinicius Costa Gomes <vinicius.gomes@intel.com>",
        "To": "netdev@vger.kernel.org",
        "Date": "Thu, 31 Aug 2017 18:26:24 -0700",
        "Message-Id": "<20170901012625.14838-5-vinicius.gomes@intel.com>",
        "X-Mailer": "git-send-email 2.14.1",
        "In-Reply-To": "<20170901012625.14838-1-vinicius.gomes@intel.com>",
        "References": "<20170901012625.14838-1-vinicius.gomes@intel.com>",
        "MIME-Version": "1.0",
        "X-Mailman-Approved-At": "Fri, 01 Sep 2017 21:24:44 +0000",
        "Cc": "andre.guedes@intel.com, jiri@resnulli.us, ivan.briano@intel.com,\n\tVinicius Costa Gomes <vinicius.gomes@intel.com>,\n\trichardcochran@gmail.com, \n\tjhs@mojatatu.com, intel-wired-lan@lists.osuosl.org,\n\tboon.leong.ong@intel.com, xiyou.wangcong@gmail.com,\n\tJesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>",
        "Subject": "[Intel-wired-lan] [RFC net-next 4/5] sample: Add TSN Talker and\n\tListener examples",
        "X-BeenThere": "intel-wired-lan@osuosl.org",
        "X-Mailman-Version": "2.1.18-1",
        "Precedence": "list",
        "List-Id": "Intel Wired Ethernet Linux Kernel Driver Development\n\t<intel-wired-lan.osuosl.org>",
        "List-Unsubscribe": "<https://lists.osuosl.org/mailman/options/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.osuosl.org/pipermail/intel-wired-lan/>",
        "List-Post": "<mailto:intel-wired-lan@osuosl.org>",
        "List-Help": "<mailto:intel-wired-lan-request@osuosl.org?subject=help>",
        "List-Subscribe": "<https://lists.osuosl.org/mailman/listinfo/intel-wired-lan>, \n\t<mailto:intel-wired-lan-request@osuosl.org?subject=subscribe>",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Errors-To": "intel-wired-lan-bounces@osuosl.org",
        "Sender": "\"Intel-wired-lan\" <intel-wired-lan-bounces@osuosl.org>"
    },
    "content": "From: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>\n\nAdd two examples so one can easily test a 'TSN distributed system'\nrunning with standard kernel interfaces. Both 'talker' and 'listener'\nsides are provided, and use a AF_PACKET for Tx / Rx of frames.\n\nRunning the examples is rather simple.\nFor the talker, just the interface and SO_PRIORITY are expected as\nparameters:\n\n$ ./talker -i enp3s0 -p 3\n\nFor the listener, only the interface is needed:\n\n$ ./listener -i enp3s0\n\nThe multicast MAC address being used is currently hardcoded on both\nexamples for simplicity.\n\nNote that the listener side uses a BPF filter so only frames sent to\nthe correct \"stream\" destination address are received by the socket.\nIf you modify the address used by the talker, you must also adapt\nthe BPF filter otherwise no frames will be received by the socket.\n\nThe listener example will print the rate of packets reception after\nevery 1 second. This makes it easier to verify if the bandwidth\nconfigured for a traffic class is being respected or not.\n\nSigned-off-by: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>\nSigned-off-by: Vinicius Costa Gomes <vinicius.gomes@intel.com>\nSigned-off-by: Andre Guedes <andre.guedes@intel.com>\nSigned-off-by: Iván Briano <ivan.briano@intel.com>\n---\n samples/tsn/listener.c | 254 +++++++++++++++++++++++++++++++++++++++++++++++++\n samples/tsn/talker.c   | 136 ++++++++++++++++++++++++++\n 2 files changed, 390 insertions(+)\n create mode 100644 samples/tsn/listener.c\n create mode 100644 samples/tsn/talker.c",
    "diff": "diff --git a/samples/tsn/listener.c b/samples/tsn/listener.c\nnew file mode 100644\nindex 000000000000..2d17bdfbea99\n--- /dev/null\n+++ b/samples/tsn/listener.c\n@@ -0,0 +1,254 @@\n+/*\n+ * Copyright (c) 2017, Intel Corporation\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright notice,\n+ *       this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in the\n+ *       documentation and/or other materials provided with the distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its contributors\n+ *       may be used to endorse or promote products derived from this software\n+ *       without specific prior written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n+ * OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <alloca.h>\n+#include <argp.h>\n+#include <arpa/inet.h>\n+#include <inttypes.h>\n+#include <linux/filter.h>\n+#include <linux/if.h>\n+#include <linux/if_ether.h>\n+#include <linux/if_packet.h>\n+#include <poll.h>\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <string.h>\n+#include <sys/ioctl.h>\n+#include <sys/timerfd.h>\n+#include <unistd.h>\n+\n+#define MAX_FRAME_SIZE 1500\n+\n+/* XXX: If this address is changed, the BPF filter must be adjusted. */\n+static uint8_t multicast_macaddr[] = { 0xBB, 0xAA, 0xBB, 0xAA, 0xBB, 0xAA };\n+static char ifname[IFNAMSIZ];\n+static uint64_t data_count;\n+static int arg_count;\n+\n+/*\n+ * BPF Filter so we only receive frames from the destination MAC address of our\n+ * SRP stream. This is hardcoded in multicast_macaddr[].\n+ */\n+static struct sock_filter dst_addr_filter[] = {\n+\t{ 0x20,  0,  0, 0000000000 }, /* Load DST address: first 32bits only */\n+\t{ 0x15,  0,  3, 0xbbaabbaa }, /* Compare with first 32bits from MAC */\n+\t{ 0x28,  0,  0, 0x00000004 }, /* Load DST address: remaining 16bits */\n+\t{ 0x15,  0,  1, 0x0000bbaa }, /* Compare with last 16bits from MAC */\n+\t{ 0x06,  0,  0, 0xffffffff },\n+\t{ 0x06,  0,  0, 0000000000 }, /* Ret 0. Jump here if any mismatches. */\n+};\n+\n+/* BPF program */\n+static struct sock_fprog bpf = {\n+\t.len = 6, /* Number of instructions on BPF filter */\n+\t.filter = dst_addr_filter,\n+};\n+\n+static struct argp_option options[] = {\n+\t{\"ifname\", 'i', \"IFNAME\", 0, \"Network Interface\" },\n+\t{ 0 }\n+};\n+\n+static error_t parser(int key, char *arg, struct argp_state *s)\n+{\n+\tswitch (key) {\n+\tcase 'i':\n+\t\tstrncpy(ifname, arg, sizeof(ifname) - 1);\n+\t\targ_count++;\n+\t\tbreak;\n+\tcase ARGP_KEY_END:\n+\t\tif (arg_count < 1)\n+\t\t\targp_failure(s, 1, 0, \"Options missing. Check --help\");\n+\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static struct argp argp = { options, parser };\n+\n+static int setup_1s_timer(void)\n+{\n+\tstruct itimerspec tspec = { 0 };\n+\tint fd, res;\n+\n+\tfd = timerfd_create(CLOCK_MONOTONIC, 0);\n+\tif (fd < 0) {\n+\t\tperror(\"Couldn't create timer\");\n+\t\treturn -1;\n+\t}\n+\n+\ttspec.it_value.tv_sec = 1;\n+\ttspec.it_interval.tv_sec = 1;\n+\n+\tres = timerfd_settime(fd, 0, &tspec, NULL);\n+\tif (res < 0) {\n+\t\tperror(\"Couldn't set timer\");\n+\t\tclose(fd);\n+\t\treturn -1;\n+\t}\n+\n+\treturn fd;\n+}\n+\n+static int setup_socket(void)\n+{\n+\tstruct sockaddr_ll sk_addr = {\n+\t\t.sll_family = AF_PACKET,\n+\t\t.sll_protocol = htons(ETH_P_TSN),\n+\t};\n+\tstruct packet_mreq mreq;\n+\tstruct ifreq req;\n+\tint fd, res;\n+\n+\tfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_TSN));\n+\tif (fd < 0) {\n+\t\tperror(\"Couldn't open socket\");\n+\t\treturn -1;\n+\t}\n+\n+\tres = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf));\n+\tif (res < 0) {\n+\t\tperror(\"Couldn't attach bpf filter\");\n+\t\tgoto err;\n+\t}\n+\n+\tstrncpy(req.ifr_name, ifname, sizeof(req.ifr_name));\n+\tres = ioctl(fd, SIOCGIFINDEX, &req);\n+\tif (res < 0) {\n+\t\tperror(\"Couldn't get interface index\");\n+\t\tgoto err;\n+\t}\n+\n+\tsk_addr.sll_ifindex = req.ifr_ifindex;\n+\tres = bind(fd, (struct sockaddr *) &sk_addr, sizeof(sk_addr));\n+\tif (res < 0) {\n+\t\tperror(\"Couldn't bind() to interface\");\n+\t\tgoto err;\n+\t}\n+\n+\t/* Use PACKET_ADD_MEMBERSHIP to add a binding to the Multicast Addr */\n+\tmreq.mr_ifindex = sk_addr.sll_ifindex;\n+\tmreq.mr_type = PACKET_MR_MULTICAST;\n+\tmreq.mr_alen = ETH_ALEN;\n+\tmemcpy(&mreq.mr_address, multicast_macaddr, ETH_ALEN);\n+\n+\tres = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,\n+\t\t\t\t&mreq, sizeof(struct packet_mreq));\n+\tif (res < 0) {\n+\t\tperror(\"Couldn't set PACKET_ADD_MEMBERSHIP\");\n+\t\tgoto err;\n+\t}\n+\n+\treturn fd;\n+\n+err:\n+\tclose(fd);\n+\treturn -1;\n+}\n+\n+static void recv_packet(int fd)\n+{\n+\tuint8_t *data = alloca(MAX_FRAME_SIZE);\n+\tssize_t n = recv(fd, data, MAX_FRAME_SIZE, 0);\n+\n+\tif (n < 0) {\n+\t\tperror(\"Failed to receive data\");\n+\t\treturn;\n+\t}\n+\n+\tif (n != MAX_FRAME_SIZE)\n+\t\tprintf(\"Size mismatch: expected %d, got %zd\\n\",\n+\t\t       MAX_FRAME_SIZE, n);\n+\n+\tdata_count += n;\n+}\n+\n+static void report_bw(int fd)\n+{\n+\tuint64_t expirations;\n+\tssize_t n = read(fd, &expirations, sizeof(uint64_t));\n+\n+\tif (n < 0) {\n+\t\tperror(\"Couldn't read timerfd\");\n+\t\treturn;\n+\t}\n+\n+\tif (expirations != 1)\n+\t\tprintf(\"Something went wrong with timerfd\\n\");\n+\n+\t/* Report how much data was received in 1s. */\n+\tprintf(\"Data rate: %zu kbps\\n\", (data_count * 8) / 1000);\n+\n+\tdata_count = 0;\n+}\n+\n+int main(int argc, char *argv[])\n+{\n+\tint sk_fd, timer_fd, res;\n+\tstruct pollfd fds[2];\n+\n+\targp_parse(&argp, argc, argv, 0, NULL, NULL);\n+\n+\tsk_fd = setup_socket();\n+\tif (sk_fd < 0)\n+\t\treturn 1;\n+\n+\ttimer_fd = setup_1s_timer();\n+\tif (timer_fd < 0) {\n+\t\tclose(sk_fd);\n+\t\treturn 1;\n+\t}\n+\n+\tfds[0].fd = sk_fd;\n+\tfds[0].events = POLLIN;\n+\tfds[1].fd = timer_fd;\n+\tfds[1].events = POLLIN;\n+\n+\tprintf(\"Waiting for packets...\\n\");\n+\n+\twhile (1) {\n+\t\tres = poll(fds, 2, -1);\n+\t\tif (res < 0) {\n+\t\t\tperror(\"Error on poll()\");\n+\t\t\tgoto err;\n+\t\t}\n+\n+\t\tif (fds[0].revents & POLLIN)\n+\t\t\trecv_packet(fds[0].fd);\n+\n+\t\tif (fds[1].revents & POLLIN)\n+\t\t\treport_bw(fds[1].fd);\n+\t}\n+\n+err:\n+\tclose(timer_fd);\n+\tclose(sk_fd);\n+\treturn 1;\n+}\ndiff --git a/samples/tsn/talker.c b/samples/tsn/talker.c\nnew file mode 100644\nindex 000000000000..35e6f99b48f6\n--- /dev/null\n+++ b/samples/tsn/talker.c\n@@ -0,0 +1,136 @@\n+/*\n+ * Copyright (c) 2017, Intel Corporation\n+ *\n+ * Redistribution and use in source and binary forms, with or without\n+ * modification, are permitted provided that the following conditions are met:\n+ *\n+ *     * Redistributions of source code must retain the above copyright notice,\n+ *       this list of conditions and the following disclaimer.\n+ *     * Redistributions in binary form must reproduce the above copyright\n+ *       notice, this list of conditions and the following disclaimer in the\n+ *       documentation and/or other materials provided with the distribution.\n+ *     * Neither the name of Intel Corporation nor the names of its contributors\n+ *       may be used to endorse or promote products derived from this software\n+ *       without specific prior written permission.\n+ *\n+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n+ * \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n+ * OF THE POSSIBILITY OF SUCH DAMAGE.\n+ */\n+\n+#include <alloca.h>\n+#include <argp.h>\n+#include <arpa/inet.h>\n+#include <inttypes.h>\n+#include <linux/if.h>\n+#include <linux/if_ether.h>\n+#include <linux/if_packet.h>\n+#include <stdio.h>\n+#include <stdlib.h>\n+#include <string.h>\n+#include <sys/ioctl.h>\n+#include <unistd.h>\n+\n+#define MAX_FRAME_SIZE 1500\n+\n+static uint8_t multicast_macaddr[] = { 0xBB, 0xAA, 0xBB, 0xAA, 0xBB, 0xAA };\n+static char ifname[IFNAMSIZ];\n+static int prio = -1;\n+static int arg_count;\n+\n+static struct argp_option options[] = {\n+\t{\"ifname\", 'i', \"IFNAME\", 0, \"Network Interface\" },\n+\t{\"prio\", 'p', \"NUM\", 0, \"SO_PRIORITY to be set in socket\" },\n+\t{ 0 }\n+};\n+\n+static error_t parser(int key, char *arg, struct argp_state *s)\n+{\n+\tswitch (key) {\n+\tcase 'i':\n+\t\tstrncpy(ifname, arg, sizeof(ifname) - 1);\n+\t\targ_count++;\n+\t\tbreak;\n+\tcase 'p':\n+\t\tprio = atoi(arg);\n+\t\tif (prio < 0)\n+\t\t\targp_failure(s, 1, 0, \"Priority must be >=0\\n\");\n+\t\targ_count++;\n+\t\tbreak;\n+\tcase ARGP_KEY_END:\n+\t\tif (arg_count < 2)\n+\t\t\targp_failure(s, 1, 0,\n+\t\t\t\t     \"Options missing. Check --help\\n\");\n+\t\tbreak;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static struct argp argp = { options, parser };\n+\n+int main(int argc, char *argv[])\n+{\n+\tstruct sockaddr_ll dst_ll_addr = {\n+\t\t.sll_family = AF_PACKET,\n+\t\t.sll_protocol = htons(ETH_P_TSN),\n+\t\t.sll_halen = ETH_ALEN,\n+\t};\n+\tstruct ifreq req;\n+\tuint8_t *payload;\n+\tint fd, res;\n+\n+\targp_parse(&argp, argc, argv, 0, NULL, NULL);\n+\n+\tfd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_TSN));\n+\tif (fd < 0) {\n+\t\tperror(\"Couldn't open socket\");\n+\t\treturn 1;\n+\t}\n+\n+\tstrncpy(req.ifr_name, ifname, sizeof(req.ifr_name));\n+\tres = ioctl(fd, SIOCGIFINDEX, &req);\n+\tif (res < 0) {\n+\t\tperror(\"Couldn't get interface index\");\n+\t\tgoto err;\n+\t}\n+\n+\tdst_ll_addr.sll_ifindex = req.ifr_ifindex;\n+\tmemcpy(&dst_ll_addr.sll_addr, multicast_macaddr, ETH_ALEN);\n+\n+\tres = setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio));\n+\tif (res < 0) {\n+\t\tperror(\"Couldn't set priority\");\n+\t\tgoto err;\n+\t}\n+\n+\tpayload = alloca(MAX_FRAME_SIZE);\n+\tmemset(payload, 0xBE, MAX_FRAME_SIZE);\n+\n+\tprintf(\"Sending packets...\\n\");\n+\n+\twhile (1) {\n+\t\tssize_t n = sendto(fd, payload, MAX_FRAME_SIZE, 0,\n+\t\t\t\t(struct sockaddr *) &dst_ll_addr,\n+\t\t\t\tsizeof(dst_ll_addr));\n+\n+\t\tif (n < 0)\n+\t\t\tperror(\"Failed to send data\");\n+\n+\t\t/* Sleep for 500us to avoid starvation from a 20Mbps stream. */\n+\t\tusleep(500);\n+\t}\n+\n+err:\n+\tclose(fd);\n+\treturn 1;\n+}\n",
    "prefixes": [
        "RFC",
        "net-next",
        "4/5"
    ]
}