Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c4787643 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: qrtr: Align header and payload"

parents 7f16200f 6edb7067
Loading
Loading
Loading
Loading
+19 −40
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2015, Sony Mobile Communications Inc.
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 * Copyright (c) 2013, 2018 The Linux Foundation. All rights reserved.
 */
#include <linux/module.h>
#include <linux/netlink.h>
@@ -157,6 +157,8 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,
			      int type, struct sockaddr_qrtr *from,
			      struct sockaddr_qrtr *to);
static struct qrtr_sock *qrtr_port_lookup(int port);
static void qrtr_port_put(struct qrtr_sock *ipc);

/* Release node resources and free the node.
 *
@@ -184,7 +186,6 @@ static void __qrtr_node_release(struct kref *kref)
		kfree(*slot);
	}

	cancel_work_sync(&node->work);
	skb_queue_purge(&node->rx_queue);
	kfree(node);
}
@@ -357,7 +358,7 @@ static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
	hdr->size = cpu_to_le32(len);
	hdr->confirm_rx = !!confirm_rx;

	skb_put_padto(skb, ALIGN(len, 4));
	skb_put_padto(skb, ALIGN(len, 4) + sizeof(*hdr));

	mutex_lock(&node->ep_lock);
	if (node->ep)
@@ -422,6 +423,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_v1 *v1;
	const struct qrtr_hdr_v2 *v2;
	struct qrtr_sock *ipc;
	struct sk_buff *skb;
	struct qrtr_cb *cb;
	unsigned int size;
@@ -486,8 +488,20 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)

	skb_put_data(skb, data + hdrlen, size);

	skb_queue_tail(&node->rx_queue, skb);
	schedule_work(&node->work);
	qrtr_node_assign(node, cb->src_node);

	if (cb->type == QRTR_TYPE_RESUME_TX) {
		qrtr_tx_resume(node, skb);
	} else {
		ipc = qrtr_port_lookup(cb->dst_port);
		if (!ipc)
			goto err;

		if (sock_queue_rcv_skb(&ipc->sk, skb))
			goto err;

		qrtr_port_put(ipc);
	}

	return 0;

@@ -522,40 +536,6 @@ static struct sk_buff *qrtr_alloc_ctrl_packet(struct qrtr_ctrl_pkt **pkt)
	return skb;
}

static struct qrtr_sock *qrtr_port_lookup(int port);
static void qrtr_port_put(struct qrtr_sock *ipc);

/* Handle and route a received packet.
 *
 * This will auto-reply with resume-tx packet as necessary.
 */
static void qrtr_node_rx_work(struct work_struct *work)
{
	struct qrtr_node *node = container_of(work, struct qrtr_node, work);
	struct sk_buff *skb;

	while ((skb = skb_dequeue(&node->rx_queue)) != NULL) {
		struct qrtr_sock *ipc;
		struct qrtr_cb *cb = (struct qrtr_cb *)skb->cb;

		qrtr_node_assign(node, cb->src_node);

		if (cb->type == QRTR_TYPE_RESUME_TX) {
			qrtr_tx_resume(node, skb);
		} else {
			ipc = qrtr_port_lookup(cb->dst_port);
			if (!ipc) {
				kfree_skb(skb);
			} else {
				if (sock_queue_rcv_skb(&ipc->sk, skb))
					kfree_skb(skb);

				qrtr_port_put(ipc);
			}
		}
	}
}

/**
 * qrtr_endpoint_register() - register a new endpoint
 * @ep: endpoint to register
@@ -575,7 +555,6 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int nid)
	if (!node)
		return -ENOMEM;

	INIT_WORK(&node->work, qrtr_node_rx_work);
	kref_init(&node->ref);
	mutex_init(&node->ep_lock);
	skb_queue_head_init(&node->rx_queue);