From patchwork Thu Oct 5 03:51:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bjorn Andersson X-Patchwork-Id: 114834 Delivered-To: patch@linaro.org Received: by 10.140.22.163 with SMTP id 32csp143214qgn; Wed, 4 Oct 2017 20:51:24 -0700 (PDT) X-Received: by 10.99.191.6 with SMTP id v6mr20864518pgf.284.1507175484013; Wed, 04 Oct 2017 20:51:24 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1507175484; cv=none; d=google.com; s=arc-20160816; b=H+Rhd1SrvOIeub1O74bcKCj55jc6pCOKwJ+a6VS7vigyOxqdvUcfP+r16VJciBp2oO 9YiNnv4OVnsqHV/oAWfOvqrTKdI5MNRnQplyWcdCaXrewaNMQosILAAFF7C9GKNZHtas VQqE4q99gyFk1nRHoVXdFQWL7t/zgjeYte4eWSGoI7kJ/evnH11KuDq6mGf7erzrujke 5+V15UP5TWnSgVMnvbIygCuXAcTz6NNqY3Bdrr0bfgxqVFyGaT8a+k0InUfx36Vyns3T 3yAH5DdPMYkZwj72yO0MdjaQTlbhls5EX7IPe2Je8Wdv8Sd0ktdYFJPsAdc2W0WAadb2 ZNlg== 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=XSXd6XSHEo4F8R7K94DBJNr95E69fSrjGOUPgJgwOP4=; b=FF+aFpZOK/Xb7wgh5BQ32E7YeAgqD2LPj6dMACaFUW4GxFMtUzHC3rSWPGmT/eq0qm nBB1SkZ7+pKrRN/S/KnKxdMkPA52javQosp9awJDB66gvpv9jXOlgeHozwfsBMVD2ckE 8dZXAeq1Yc8TeNK+UnQnPQV5mpEuGzbOXFp7u1a9ZaJACiy9ccdrgqAiGiJDIoGiSKnS Wx/G3uhqnJa2fnCdTkLSeW2tPSE7gzJ9yFMpG22KXbfYAjoT+C9dAcmsZ7UQVX2cqUVv 5C1LOT/FXndBT8AUryj+LpiNIumzBs8bj7v3ZS+d659uu5qeYYFMVNdopj9c5X2zMQHh pQWg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jrdtbJmq; 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 y21si13416539pll.578.2017.10.04.20.51.23; Wed, 04 Oct 2017 20:51:23 -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=jrdtbJmq; 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 S1751967AbdJEDvV (ORCPT + 26 others); Wed, 4 Oct 2017 23:51:21 -0400 Received: from mail-pf0-f174.google.com ([209.85.192.174]:45329 "EHLO mail-pf0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751926AbdJEDvS (ORCPT ); Wed, 4 Oct 2017 23:51:18 -0400 Received: by mail-pf0-f174.google.com with SMTP id z84so7325226pfi.2 for ; Wed, 04 Oct 2017 20:51:18 -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=XSXd6XSHEo4F8R7K94DBJNr95E69fSrjGOUPgJgwOP4=; b=jrdtbJmqWvrlCLHfFaaFSBTIKY/5W+ZAoRtNeB3IGJ41+nTG9kSlnRIy9212cbzMgI MgBfyWzXIllFqfwnmxB0ynWt2xFzCJgrknMVX6+42p+d+sCDx6Xks9pvQ+UmjgEn4lR1 wS+oJ1kNnZIIA3An+D/pFw8zjZt/Osf/6qLUE= 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=XSXd6XSHEo4F8R7K94DBJNr95E69fSrjGOUPgJgwOP4=; b=EGDCpbh0/UT8RgLLA4krZwJGOeLsaWjoONgaJyY14ZHokKBJPaLx+FCdYjnJlsycVu 4MH7j7bi6HuDKWX3A81mIODiuTdaQW4ZwOVmGwgUnHFS57DPei7Z17oqNkFIFxonVOdp cJ4Txat8qOIoLr8vkol3rcmkdZS0kgjkyiflcCkWcmjnCsZV+xpIfDEnbSQ15PIZCqJy xEbuM8P86KBv24qWecZnuE9rlR+fxcv5GKUVT+Sep6IB0KmTZvfqvMDG0l78skdo3g4w lbtg94A3ZUG8nj0xZbjYMEX5SIf+PxUOy/Ymliavecd1Sq7WwLxTCYrB3M7nfYZVkIqX s2Ww== X-Gm-Message-State: AHPjjUhAWsJdAHNopfN94QCDnT4t3WFaCglxtGtEoVlJ5FQvQp9Wjzam yJUFLWQh+eIwv5AJrCDP61bwhQ== X-Google-Smtp-Source: AOwi7QAfwoi881q+O/rDsuI2IGC4MbM5otff/0UF9dPg4zfCkkx4h9NuAnyv57lZ/GAFiJgRVyfaaA== X-Received: by 10.98.223.88 with SMTP id u85mr22553216pfg.219.1507175477882; Wed, 04 Oct 2017 20:51:17 -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 f131sm13067035pfc.27.2017.10.04.20.51.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 04 Oct 2017 20:51:17 -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: [RESEND PATCH 7/7] net: qrtr: Support decoding incoming v2 packets Date: Wed, 4 Oct 2017 20:51:05 -0700 Message-Id: <20171005035105.14677-8-bjorn.andersson@linaro.org> X-Mailer: git-send-email 2.12.0 In-Reply-To: <20171005035105.14677-1-bjorn.andersson@linaro.org> References: <20171005035105.14677-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 7bca6ec892a5..8bb3e2bb5d0a 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) {