summaryrefslogtreecommitdiffstats
path: root/net/qrtr
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@linaro.org>2017-10-11 02:45:22 -0400
committerDavid S. Miller <davem@davemloft.net>2017-10-11 18:28:38 -0400
commitf507a9b6e63b9f41b61d199c36ae046d17b5fe4b (patch)
tree23a9e232943d8be2e488a67e406133ab2230d438 /net/qrtr
parent1a7959c76641674991ba3a49f25432f1e105391e (diff)
net: qrtr: Use sk_buff->cb in receive path
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 <bjorn.andersson@linaro.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/qrtr')
-rw-r--r--net/qrtr/qrtr.c70
1 files changed, 40 insertions, 30 deletions
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index a84edba7b1ef..7bca6ec892a5 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -48,6 +48,16 @@ struct qrtr_hdr {
48 __le32 dst_port_id; 48 __le32 dst_port_id;
49} __packed; 49} __packed;
50 50
51struct qrtr_cb {
52 u32 src_node;
53 u32 src_port;
54 u32 dst_node;
55 u32 dst_port;
56
57 u8 type;
58 u8 confirm_rx;
59};
60
51#define QRTR_HDR_SIZE sizeof(struct qrtr_hdr) 61#define QRTR_HDR_SIZE sizeof(struct qrtr_hdr)
52 62
53struct qrtr_sock { 63struct qrtr_sock {
@@ -216,6 +226,7 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
216 struct qrtr_node *node = ep->node; 226 struct qrtr_node *node = ep->node;
217 const struct qrtr_hdr *phdr = data; 227 const struct qrtr_hdr *phdr = data;
218 struct sk_buff *skb; 228 struct sk_buff *skb;
229 struct qrtr_cb *cb;
219 unsigned int psize; 230 unsigned int psize;
220 unsigned int size; 231 unsigned int size;
221 unsigned int type; 232 unsigned int type;
@@ -245,8 +256,15 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
245 if (!skb) 256 if (!skb)
246 return -ENOMEM; 257 return -ENOMEM;
247 258
248 skb_reset_transport_header(skb); 259 cb = (struct qrtr_cb *)skb->cb;
249 skb_put_data(skb, data, len); 260 cb->src_node = le32_to_cpu(phdr->src_node_id);
261 cb->src_port = le32_to_cpu(phdr->src_port_id);
262 cb->dst_node = le32_to_cpu(phdr->dst_node_id);
263 cb->dst_port = le32_to_cpu(phdr->dst_port_id);
264 cb->type = type;
265 cb->confirm_rx = !!phdr->confirm_rx;
266
267 skb_put_data(skb, data + QRTR_HDR_SIZE, size);
250 268
251 skb_queue_tail(&node->rx_queue, skb); 269 skb_queue_tail(&node->rx_queue, skb);
252 schedule_work(&node->work); 270 schedule_work(&node->work);
@@ -295,26 +313,20 @@ static void qrtr_node_rx_work(struct work_struct *work)
295 struct sk_buff *skb; 313 struct sk_buff *skb;
296 314
297 while ((skb = skb_dequeue(&node->rx_queue)) != NULL) { 315 while ((skb = skb_dequeue(&node->rx_queue)) != NULL) {
298 const struct qrtr_hdr *phdr;
299 u32 dst_node, dst_port;
300 struct qrtr_sock *ipc; 316 struct qrtr_sock *ipc;
301 u32 src_node; 317 struct qrtr_cb *cb;
302 int confirm; 318 int confirm;
303 319
304 phdr = (const struct qrtr_hdr *)skb_transport_header(skb); 320 cb = (struct qrtr_cb *)skb->cb;
305 src_node = le32_to_cpu(phdr->src_node_id); 321 src.sq_node = cb->src_node;
306 dst_node = le32_to_cpu(phdr->dst_node_id); 322 src.sq_port = cb->src_port;
307 dst_port = le32_to_cpu(phdr->dst_port_id); 323 dst.sq_node = cb->dst_node;
308 confirm = !!phdr->confirm_rx; 324 dst.sq_port = cb->dst_port;
325 confirm = !!cb->confirm_rx;
309 326
310 src.sq_node = src_node; 327 qrtr_node_assign(node, cb->src_node);
311 src.sq_port = le32_to_cpu(phdr->src_port_id);
312 dst.sq_node = dst_node;
313 dst.sq_port = dst_port;
314 328
315 qrtr_node_assign(node, src_node); 329 ipc = qrtr_port_lookup(cb->dst_port);
316
317 ipc = qrtr_port_lookup(dst_port);
318 if (!ipc) { 330 if (!ipc) {
319 kfree_skb(skb); 331 kfree_skb(skb);
320 } else { 332 } else {
@@ -604,7 +616,7 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
604 struct sockaddr_qrtr *to) 616 struct sockaddr_qrtr *to)
605{ 617{
606 struct qrtr_sock *ipc; 618 struct qrtr_sock *ipc;
607 struct qrtr_hdr *phdr; 619 struct qrtr_cb *cb;
608 620
609 ipc = qrtr_port_lookup(to->sq_port); 621 ipc = qrtr_port_lookup(to->sq_port);
610 if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */ 622 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,
612 return -ENODEV; 624 return -ENODEV;
613 } 625 }
614 626
615 phdr = skb_push(skb, QRTR_HDR_SIZE); 627 cb = (struct qrtr_cb *)skb->cb;
616 skb_reset_transport_header(skb); 628 cb->src_node = from->sq_node;
617 629 cb->src_port = from->sq_port;
618 phdr->src_node_id = cpu_to_le32(from->sq_node);
619 phdr->src_port_id = cpu_to_le32(from->sq_port);
620 630
621 if (sock_queue_rcv_skb(&ipc->sk, skb)) { 631 if (sock_queue_rcv_skb(&ipc->sk, skb)) {
622 qrtr_port_put(ipc); 632 qrtr_port_put(ipc);
@@ -750,9 +760,9 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg,
750 size_t size, int flags) 760 size_t size, int flags)
751{ 761{
752 DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name); 762 DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name);
753 const struct qrtr_hdr *phdr;
754 struct sock *sk = sock->sk; 763 struct sock *sk = sock->sk;
755 struct sk_buff *skb; 764 struct sk_buff *skb;
765 struct qrtr_cb *cb;
756 int copied, rc; 766 int copied, rc;
757 767
758 lock_sock(sk); 768 lock_sock(sk);
@@ -769,22 +779,22 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg,
769 return rc; 779 return rc;
770 } 780 }
771 781
772 phdr = (const struct qrtr_hdr *)skb_transport_header(skb); 782 copied = skb->len;
773 copied = le32_to_cpu(phdr->size);
774 if (copied > size) { 783 if (copied > size) {
775 copied = size; 784 copied = size;
776 msg->msg_flags |= MSG_TRUNC; 785 msg->msg_flags |= MSG_TRUNC;
777 } 786 }
778 787
779 rc = skb_copy_datagram_msg(skb, QRTR_HDR_SIZE, msg, copied); 788 rc = skb_copy_datagram_msg(skb, 0, msg, copied);
780 if (rc < 0) 789 if (rc < 0)
781 goto out; 790 goto out;
782 rc = copied; 791 rc = copied;
783 792
784 if (addr) { 793 if (addr) {
794 cb = (struct qrtr_cb *)skb->cb;
785 addr->sq_family = AF_QIPCRTR; 795 addr->sq_family = AF_QIPCRTR;
786 addr->sq_node = le32_to_cpu(phdr->src_node_id); 796 addr->sq_node = cb->src_node;
787 addr->sq_port = le32_to_cpu(phdr->src_port_id); 797 addr->sq_port = cb->src_port;
788 msg->msg_namelen = sizeof(*addr); 798 msg->msg_namelen = sizeof(*addr);
789 } 799 }
790 800
@@ -877,7 +887,7 @@ static int qrtr_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
877 case TIOCINQ: 887 case TIOCINQ:
878 skb = skb_peek(&sk->sk_receive_queue); 888 skb = skb_peek(&sk->sk_receive_queue);
879 if (skb) 889 if (skb)
880 len = skb->len - QRTR_HDR_SIZE; 890 len = skb->len;
881 rc = put_user(len, (int __user *)argp); 891 rc = put_user(len, (int __user *)argp);
882 break; 892 break;
883 case SIOCGIFADDR: 893 case SIOCGIFADDR: