From patchwork Thu Sep 7 06:03:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 111858 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp357013qge; Wed, 6 Sep 2017 23:04:02 -0700 (PDT) X-Received: by 10.84.132.1 with SMTP id 1mr1734005ple.253.1504764242289; Wed, 06 Sep 2017 23:04:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504764242; cv=none; d=google.com; s=arc-20160816; b=sbQ4W6/2s416KtjRvkzepqhFImBKN9YmeN5TLSkbc7uImskQsSU1qYS147CQ62Bvaj jdj6jXxaSfc+RneE1u7wuDHKDE8pI06EPaVrsTX8Na4iT/OXngpWeKvIoWrCohKe23Vw n1Jeka3uKPgt0drEnPFxR0S8+jTPMYeKSM66y+bijr3kB+WXiYPqVVLgkWiCXFMVQjgk RZYWlaML0/ffiJS2o9W7pZJjdqEW9je2vqU3Ma6Q62puesGzdFCSYWLmHdMDusnPLIRJ Wl8MbU67VgKKFZEyXY6h2Gblbtq5OSfzsN94FL+KsuAgETmdSq5mcQrWGml01P6+bkYg cySQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=/thH9etSK4B+8rLqtVVQ/Jd8bt8cVU+Vh5nH0wQcye8=; b=M6LkYPe7YHbZai9usBv+OvVe58Vs5uldIKfqrdfleTqUTW1Bg6aipjD8JTl+OHQ6Tp ozEAzFNLAjG6slcdbRYFD/IFe6p7IgvFc5cz2SI7YluUKI6GJxm3iGM4sjuLNLDCwVR5 xyD1QnttjSauUvdOIq2Yd6Gv72WKR2w09RKPvfynIR04rlHW4hoaA9D6Sa4tBqNGhpXg eQF837mUyY41bkQSH2H9ra0L1PaPb+pIH08vfYRsgIp8UFf2OFQVQQCMvGdD+F+NELng QNqsyoDMc6w/Zf8mLAPmeRAQj/+C6mhz6h3JqtjV6zcMQCjG097RYHqdyUqHFzEX/z63 ao6w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=j1vbo/tK; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u123si1355978pgc.27.2017.09.06.23.04.02; Wed, 06 Sep 2017 23:04:02 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=j1vbo/tK; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754177AbdIGGDs (ORCPT + 26 others); Thu, 7 Sep 2017 02:03:48 -0400 Received: from mail-pg0-f51.google.com ([74.125.83.51]:38662 "EHLO mail-pg0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754023AbdIGGDl (ORCPT ); Thu, 7 Sep 2017 02:03:41 -0400 Received: by mail-pg0-f51.google.com with SMTP id v66so19132277pgb.5 for ; Wed, 06 Sep 2017 23:03:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=/thH9etSK4B+8rLqtVVQ/Jd8bt8cVU+Vh5nH0wQcye8=; b=j1vbo/tKXHVzgG39CyBcP99h5BToxM24LgHviGFnwSvyDWD98Y+hkt3dQ+lStcdKP+ IW230IbPVtQobF3oYSmZ0GNJ3fmmCXVeaqd7WISalBTkAOS1MxY8ASHDSFF+ZRYv9A8o 2M8chteYIRKEezdehvw6MA2tfZf/hfhyTJI8Q= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=/thH9etSK4B+8rLqtVVQ/Jd8bt8cVU+Vh5nH0wQcye8=; b=NpyyMbn99MbJZ+CFAZ2mBut+mAWbi5vwItm8t680KFiz9tj+ItxQ2XOVpwk9/cjKOv 3J1nqCbIxWEbX2tCQzIGRbXognj/WqvTyrplyfstPQgTTX6hvIz+Bmx1pgk9IuBbeQ+4 PXtAeCPrrGva3I/T/fJmnUFyERvu0Rp5lm15aVkxti4WehrzJSw9PztS+zgj2rQwItjM UVopDQ93BfoImMdvFHpvusi0Cctl5qDqdWbsQI3jg1oUx2Dd20db2dnU3q5qE38NeSwj 1vgdsoaqMuDkZ5DNN+5IzDX3HwqHOZBCaC2KXxAszW/gRRHQVfHqNjGM5F5a0MzzNNmW /nqA== X-Gm-Message-State: AHPjjUgdPx1e03XVdo8lID4OUsY1YbB9aMIsjkeJW3BbyLutA5ANpfyi Ajp3prEmTjT5AamS X-Google-Smtp-Source: ADKCNb5Q0irZ/BkvhnKP51naXW2sY0DgY/9ferenaL4cTujpB9eo9+a/Uux48ELdyqPcCCFnvq6kqw== X-Received: by 10.98.73.144 with SMTP id r16mr1598862pfi.314.1504764220515; Wed, 06 Sep 2017 23:03:40 -0700 (PDT) Received: from localhost.localdomain (ip68-111-217-79.sd.sd.cox.net. [68.111.217.79]) by smtp.gmail.com with ESMTPSA id s1sm2186650pfk.27.2017.09.06.23.03.39 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Sep 2017 23:03:40 -0700 (PDT) From: Bjorn Andersson To: "David S. Miller" Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Chris Lew Subject: [PATCH 6/7] net: qrtr: Use sk_buff->cb in receive path Date: Wed, 6 Sep 2017 23:03:28 -0700 Message-Id: <20170907060329.32402-7-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.12.0 In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org> References: <20170907060329.32402-1-bjorn.andersson@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Rather than parsing the header of incoming messages throughout the implementation do it once when we retrieve the message and store the relevant information in the "cb" member of the sk_buff. This allows us to, in a later commit, decode version 2 messages into this same structure. Signed-off-by: Bjorn Andersson --- net/qrtr/qrtr.c | 70 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 30 deletions(-) -- 2.12.0 diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index f28ecd7d735b..5042999756ce 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -48,6 +48,16 @@ struct qrtr_hdr { __le32 dst_port_id; } __packed; +struct qrtr_cb { + u32 src_node; + u32 src_port; + u32 dst_node; + u32 dst_port; + + u8 type; + u8 confirm_rx; +}; + #define QRTR_HDR_SIZE sizeof(struct qrtr_hdr) struct qrtr_sock { @@ -216,6 +226,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) struct qrtr_node *node = ep->node; const struct qrtr_hdr *phdr = data; struct sk_buff *skb; + struct qrtr_cb *cb; unsigned int psize; unsigned int size; unsigned int type; @@ -245,8 +256,15 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) if (!skb) return -ENOMEM; - skb_reset_transport_header(skb); - skb_put_data(skb, data, len); + cb = (struct qrtr_cb *)skb->cb; + cb->src_node = le32_to_cpu(phdr->src_node_id); + cb->src_port = le32_to_cpu(phdr->src_port_id); + cb->dst_node = le32_to_cpu(phdr->dst_node_id); + cb->dst_port = le32_to_cpu(phdr->dst_port_id); + cb->type = type; + cb->confirm_rx = !!phdr->confirm_rx; + + skb_put_data(skb, data + QRTR_HDR_SIZE, size); skb_queue_tail(&node->rx_queue, skb); schedule_work(&node->work); @@ -295,26 +313,20 @@ static void qrtr_node_rx_work(struct work_struct *work) struct sk_buff *skb; while ((skb = skb_dequeue(&node->rx_queue)) != NULL) { - const struct qrtr_hdr *phdr; - u32 dst_node, dst_port; struct qrtr_sock *ipc; - u32 src_node; + struct qrtr_cb *cb; int confirm; - phdr = (const struct qrtr_hdr *)skb_transport_header(skb); - src_node = le32_to_cpu(phdr->src_node_id); - dst_node = le32_to_cpu(phdr->dst_node_id); - dst_port = le32_to_cpu(phdr->dst_port_id); - confirm = !!phdr->confirm_rx; + cb = (struct qrtr_cb *)skb->cb; + src.sq_node = cb->src_node; + src.sq_port = cb->src_port; + dst.sq_node = cb->dst_node; + dst.sq_port = cb->dst_port; + confirm = !!cb->confirm_rx; - src.sq_node = src_node; - src.sq_port = le32_to_cpu(phdr->src_port_id); - dst.sq_node = dst_node; - dst.sq_port = dst_port; + qrtr_node_assign(node, cb->src_node); - qrtr_node_assign(node, src_node); - - ipc = qrtr_port_lookup(dst_port); + ipc = qrtr_port_lookup(cb->dst_port); if (!ipc) { kfree_skb(skb); } else { @@ -604,7 +616,7 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb, struct sockaddr_qrtr *to) { struct qrtr_sock *ipc; - struct qrtr_hdr *phdr; + struct qrtr_cb *cb; ipc = qrtr_port_lookup(to->sq_port); if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */ @@ -612,11 +624,9 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb, return -ENODEV; } - phdr = skb_push(skb, QRTR_HDR_SIZE); - skb_reset_transport_header(skb); - - phdr->src_node_id = cpu_to_le32(from->sq_node); - phdr->src_port_id = cpu_to_le32(from->sq_port); + cb = (struct qrtr_cb *)skb->cb; + cb->src_node = from->sq_node; + cb->src_port = from->sq_port; if (sock_queue_rcv_skb(&ipc->sk, skb)) { qrtr_port_put(ipc); @@ -750,9 +760,9 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, size_t size, int flags) { DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name); - const struct qrtr_hdr *phdr; struct sock *sk = sock->sk; struct sk_buff *skb; + struct qrtr_cb *cb; int copied, rc; lock_sock(sk); @@ -769,22 +779,22 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, return rc; } - phdr = (const struct qrtr_hdr *)skb_transport_header(skb); - copied = le32_to_cpu(phdr->size); + copied = skb->len; if (copied > size) { copied = size; msg->msg_flags |= MSG_TRUNC; } - rc = skb_copy_datagram_msg(skb, QRTR_HDR_SIZE, msg, copied); + rc = skb_copy_datagram_msg(skb, 0, msg, copied); if (rc < 0) goto out; rc = copied; if (addr) { + cb = (struct qrtr_cb *)skb->cb; addr->sq_family = AF_QIPCRTR; - addr->sq_node = le32_to_cpu(phdr->src_node_id); - addr->sq_port = le32_to_cpu(phdr->src_port_id); + addr->sq_node = cb->src_node; + addr->sq_port = cb->src_port; msg->msg_namelen = sizeof(*addr); } @@ -877,7 +887,7 @@ static int qrtr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) case TIOCINQ: skb = skb_peek(&sk->sk_receive_queue); if (skb) - len = skb->len - QRTR_HDR_SIZE; + len = skb->len; rc = put_user(len, (int __user *)argp); break; case SIOCGIFADDR: From patchwork Thu Sep 7 06:03:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 111859 Delivered-To: patch@linaro.org Received: by 10.140.94.239 with SMTP id g102csp357337qge; Wed, 6 Sep 2017 23:04:21 -0700 (PDT) X-Received: by 10.84.224.136 with SMTP id s8mr1821395plj.324.1504764261329; Wed, 06 Sep 2017 23:04:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1504764261; cv=none; d=google.com; s=arc-20160816; b=bU+8TFGszDYvGRTEYT8DTpp5vBvlry1VixLBdYqDTPjfW8WO4cEH6coGjbXQp3N/Zu nkE7V3rx0mlmjksHy4qd3HC0tiERbl5wryiCZZ4YD/9ZEC7SMPfM4E7LF71UcFtaAEYd 3edLObOWLbr2AG2FG7uQbfylly6ahi+nVYm/QRHXnUKiZnSihMgR1e36dKyQ+hxKQSlj f7/uXztylncdRkCef9AQF4L75X9dR9wMMk0BWCDOiml2EHt9BQrsQZRSGobRDlK25eBj 2wc2mXYEKJwztEm5KH/Ku2KM4YI1gvWHPq6BDmn2DyrQy35aXpBxJkNd81+dn6tbggpM +LJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=StanxJdbaw1SNc4T2/YT3g2/HEJBj5sy7ikfCMlZTNw=; b=UbgTqyVb4sz6hYlWkOEaLQALsHwomsW5iCoHscfWGTWNjvfGW0y08w2Ljt+CelPPyX BYKRHe294x/kASAgcJOAwRWvrCu85CMRgkQAB/q7G+UbH76GUiQ5JLLyjhESP6FIUqPZ 8zRoaJlucDazjyIQ/GJ/NS4J2Jq8f4JBtJ1eHw+DuatdUNAsSBbM7dfl15Z/ecEEQ7XU e7tOSPVsVH41m//9m3QvG6agu9duOwz1gcePm6TfoHHLdPSBuBbgehszQazhe6F0r7Fr Fr55tOyZ6ui0+d78s28VUt1GIll65ytJulin36QO6UpZIRNXg0SH6a39JvRNBnTN5WgK L22Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Lf1+CbSb; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q1si1383547plb.133.2017.09.06.23.04.21; Wed, 06 Sep 2017 23:04:21 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=Lf1+CbSb; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754125AbdIGGDq (ORCPT + 26 others); Thu, 7 Sep 2017 02:03:46 -0400 Received: from mail-pf0-f176.google.com ([209.85.192.176]:33129 "EHLO mail-pf0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754029AbdIGGDm (ORCPT ); Thu, 7 Sep 2017 02:03:42 -0400 Received: by mail-pf0-f176.google.com with SMTP id y68so16335939pfd.0 for ; Wed, 06 Sep 2017 23:03:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=StanxJdbaw1SNc4T2/YT3g2/HEJBj5sy7ikfCMlZTNw=; b=Lf1+CbSbMvWwAa6s9a/9JeEdmICv4g9F2ZIBa/CyTnl/9Q6/IyLTGtsZg7m8tbYeLS vFN5s50xjhtle3skj/tsQHz3eTQaJVDNDsjTl/Z8QNj93rC/LDRe5Q1QMOH4TKLjJwyM M1b5nSWdGN7DAM4gTIzcn71F/K3veEf7+b5oY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=StanxJdbaw1SNc4T2/YT3g2/HEJBj5sy7ikfCMlZTNw=; b=refWvlFK1GmhkorRrSKNlRU582QV8hVt5XLkfVEbjqyIwEC9pJ1pjdn2x+uejWOKw5 MyGUUKe33XeAnWXjxbgc53z06kvKoqbNZiiwJ9O319fQcLdiMxDQRYysuFK59gjRsL7+ sc1SrwRLn42nQ9JiIoYFOmIRTYLAkDrlg5X2vUeF717UcnTFB8bFPYdQABbBOfyRJXiS r7eb6S80cpBUso+Our+GJ8Jq7YIfn3rh7O4Qcn2rNIdJ5vXGTzPb5riDbD3TU7FYQlYM ZPrqae84AI7e9WQ3zruSf06VDbC2PSWBsbKTFkxPoMqwGec4wlcD6t+CEkD2dPLHZqIC Mhfg== X-Gm-Message-State: AHPjjUgI44hltnjHDVybpPFnhbwew2F4+7xa1GISXg1+9HoPXCNhTO+y O6c6z2LPK7Fz/+x9 X-Google-Smtp-Source: ADKCNb6N6HdHxpv+QeCttxF0zvIOjbD2Vv0on5Jyebhvj7XLPoeiSFeRjsdNmfGfcBzgEKKxrDYvvg== X-Received: by 10.98.13.81 with SMTP id v78mr1609609pfi.61.1504764221625; Wed, 06 Sep 2017 23:03:41 -0700 (PDT) Received: from localhost.localdomain (ip68-111-217-79.sd.sd.cox.net. [68.111.217.79]) by smtp.gmail.com with ESMTPSA id s1sm2186650pfk.27.2017.09.06.23.03.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 06 Sep 2017 23:03:41 -0700 (PDT) From: Bjorn Andersson To: "David S. Miller" Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, Chris Lew Subject: [PATCH 7/7] net: qrtr: Support decoding incoming v2 packets Date: Wed, 6 Sep 2017 23:03:29 -0700 Message-Id: <20170907060329.32402-8-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.12.0 In-Reply-To: <20170907060329.32402-1-bjorn.andersson@linaro.org> References: <20170907060329.32402-1-bjorn.andersson@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add the necessary logic for decoding incoming messages of version 2 as well. Also make sure there's room for the bigger of version 1 and 2 headers in the code allocating skbs for outgoing messages. Signed-off-by: Bjorn Andersson --- net/qrtr/qrtr.c | 132 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 38 deletions(-) -- 2.12.0 diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index 5042999756ce..5f397fa1c109 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -20,14 +20,15 @@ #include "qrtr.h" -#define QRTR_PROTO_VER 1 +#define QRTR_PROTO_VER_1 1 +#define QRTR_PROTO_VER_2 3 /* auto-bind range */ #define QRTR_MIN_EPH_SOCKET 0x4000 #define QRTR_MAX_EPH_SOCKET 0x7fff /** - * struct qrtr_hdr - (I|R)PCrouter packet header + * struct qrtr_hdr_v1 - (I|R)PCrouter packet header version 1 * @version: protocol version * @type: packet type; one of QRTR_TYPE_* * @src_node_id: source node @@ -37,7 +38,7 @@ * @dst_node_id: destination node * @dst_port_id: destination port */ -struct qrtr_hdr { +struct qrtr_hdr_v1 { __le32 version; __le32 type; __le32 src_node_id; @@ -48,6 +49,32 @@ struct qrtr_hdr { __le32 dst_port_id; } __packed; +/** + * struct qrtr_hdr_v2 - (I|R)PCrouter packet header later versions + * @version: protocol version + * @type: packet type; one of QRTR_TYPE_* + * @flags: bitmask of QRTR_FLAGS_* + * @optlen: length of optional header data + * @size: length of packet, excluding this header and optlen + * @src_node_id: source node + * @src_port_id: source port + * @dst_node_id: destination node + * @dst_port_id: destination port + */ +struct qrtr_hdr_v2 { + u8 version; + u8 type; + u8 flags; + u8 optlen; + __le32 size; + __le16 src_node_id; + __le16 src_port_id; + __le16 dst_node_id; + __le16 dst_port_id; +} __packed; + +#define QRTR_FLAGS_CONFIRM_RX BIT(0) + struct qrtr_cb { u32 src_node; u32 src_port; @@ -58,7 +85,8 @@ struct qrtr_cb { u8 confirm_rx; }; -#define QRTR_HDR_SIZE sizeof(struct qrtr_hdr) +#define QRTR_HDR_MAX_SIZE max_t(size_t, sizeof(struct qrtr_hdr_v1), \ + sizeof(struct qrtr_hdr_v2)) struct qrtr_sock { /* WARNING: sk must be the first member */ @@ -154,12 +182,12 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb, int type, struct sockaddr_qrtr *from, struct sockaddr_qrtr *to) { - struct qrtr_hdr *hdr; + struct qrtr_hdr_v1 *hdr; size_t len = skb->len; int rc = -ENODEV; - hdr = skb_push(skb, QRTR_HDR_SIZE); - hdr->version = cpu_to_le32(QRTR_PROTO_VER); + hdr = skb_push(skb, sizeof(*hdr)); + hdr->version = cpu_to_le32(QRTR_PROTO_VER_1); hdr->type = cpu_to_le32(type); hdr->src_node_id = cpu_to_le32(from->sq_node); hdr->src_port_id = cpu_to_le32(from->sq_port); @@ -224,52 +252,80 @@ static void qrtr_node_assign(struct qrtr_node *node, unsigned int nid) int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len) { struct qrtr_node *node = ep->node; - const struct qrtr_hdr *phdr = data; + const struct qrtr_hdr_v1 *v1; + const struct qrtr_hdr_v2 *v2; struct sk_buff *skb; struct qrtr_cb *cb; - unsigned int psize; unsigned int size; - unsigned int type; unsigned int ver; - unsigned int dst; + size_t hdrlen; - if (len < QRTR_HDR_SIZE || len & 3) + if (len & 3) return -EINVAL; - ver = le32_to_cpu(phdr->version); - size = le32_to_cpu(phdr->size); - type = le32_to_cpu(phdr->type); - dst = le32_to_cpu(phdr->dst_port_id); + skb = netdev_alloc_skb(NULL, len); + if (!skb) + return -ENOMEM; - psize = (size + 3) & ~3; + cb = (struct qrtr_cb *)skb->cb; - if (ver != QRTR_PROTO_VER) - return -EINVAL; + /* Version field in v1 is little endian, so this works for both cases */ + ver = *(u8 *)data; - if (len != psize + QRTR_HDR_SIZE) - return -EINVAL; + switch (ver) { + case QRTR_PROTO_VER_1: + v1 = data; + hdrlen = sizeof(*v1); - if (dst != QRTR_PORT_CTRL && type != QRTR_TYPE_DATA) - return -EINVAL; + cb->type = le32_to_cpu(v1->type); + cb->src_node = le32_to_cpu(v1->src_node_id); + cb->src_port = le32_to_cpu(v1->src_port_id); + cb->confirm_rx = !!v1->confirm_rx; + cb->dst_node = le32_to_cpu(v1->dst_node_id); + cb->dst_port = le32_to_cpu(v1->dst_port_id); - skb = netdev_alloc_skb(NULL, len); - if (!skb) - return -ENOMEM; + size = le32_to_cpu(v1->size); + break; + case QRTR_PROTO_VER_2: + v2 = data; + hdrlen = sizeof(*v2) + v2->optlen; + + cb->type = v2->type; + cb->confirm_rx = !!(v2->flags & QRTR_FLAGS_CONFIRM_RX); + cb->src_node = le16_to_cpu(v2->src_node_id); + cb->src_port = le16_to_cpu(v2->src_port_id); + cb->dst_node = le16_to_cpu(v2->dst_node_id); + cb->dst_port = le16_to_cpu(v2->dst_port_id); + + if (cb->src_port == (u16)QRTR_PORT_CTRL) + cb->src_port = QRTR_PORT_CTRL; + if (cb->dst_port == (u16)QRTR_PORT_CTRL) + cb->dst_port = QRTR_PORT_CTRL; + + size = le32_to_cpu(v2->size); + break; + default: + pr_err("qrtr: Invalid version %d\n", ver); + goto err; + } - cb = (struct qrtr_cb *)skb->cb; - cb->src_node = le32_to_cpu(phdr->src_node_id); - cb->src_port = le32_to_cpu(phdr->src_port_id); - cb->dst_node = le32_to_cpu(phdr->dst_node_id); - cb->dst_port = le32_to_cpu(phdr->dst_port_id); - cb->type = type; - cb->confirm_rx = !!phdr->confirm_rx; + if (len != ALIGN(size, 4) + hdrlen) + goto err; - skb_put_data(skb, data + QRTR_HDR_SIZE, size); + if (cb->dst_port != QRTR_PORT_CTRL && cb->type != QRTR_TYPE_DATA) + goto err; + + skb_put_data(skb, data + hdrlen, size); skb_queue_tail(&node->rx_queue, skb); schedule_work(&node->work); return 0; + +err: + kfree_skb(skb); + return -EINVAL; + } EXPORT_SYMBOL_GPL(qrtr_endpoint_post); @@ -287,11 +343,11 @@ static struct sk_buff *qrtr_alloc_ctrl_packet(struct qrtr_ctrl_pkt **pkt) const int pkt_len = sizeof(struct qrtr_ctrl_pkt); struct sk_buff *skb; - skb = alloc_skb(QRTR_HDR_SIZE + pkt_len, GFP_KERNEL); + skb = alloc_skb(QRTR_HDR_MAX_SIZE + pkt_len, GFP_KERNEL); if (!skb) return NULL; - skb_reserve(skb, QRTR_HDR_SIZE); + skb_reserve(skb, QRTR_HDR_MAX_SIZE); *pkt = skb_put_zero(skb, pkt_len); return skb; @@ -720,12 +776,12 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) } plen = (len + 3) & ~3; - skb = sock_alloc_send_skb(sk, plen + QRTR_HDR_SIZE, + skb = sock_alloc_send_skb(sk, plen + QRTR_HDR_MAX_SIZE, msg->msg_flags & MSG_DONTWAIT, &rc); if (!skb) goto out_node; - skb_reserve(skb, QRTR_HDR_SIZE); + skb_reserve(skb, QRTR_HDR_MAX_SIZE); rc = memcpy_from_msg(skb_put(skb, len), msg, len); if (rc) {