summaryrefslogtreecommitdiffstats
path: root/net/qrtr/qrtr.c
diff options
context:
space:
mode:
authorBjorn Andersson <bjorn.andersson@linaro.org>2017-10-11 02:45:20 -0400
committerDavid S. Miller <davem@davemloft.net>2017-10-11 18:28:38 -0400
commite7044482c8ac5081f4775063995647787d5082a4 (patch)
treeed2624b0fe609de0ff5a39ccff27d94ae1b1a666 /net/qrtr/qrtr.c
parentda7653f0faabbe45eb2d3fd6e4b400fe003e81ae (diff)
net: qrtr: Pass source and destination to enqueue functions
Defer writing the message header to the skb until its time to enqueue the packet. As the receive path is reworked to decode the message header as it's received from the transport and only pass around the payload in the skb this change means that we do not have to fill out the full message header just to decode it immediately in qrtr_local_enqueue(). In the future this change also makes it possible to prepend message headers based on the version of each link. Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/qrtr/qrtr.c')
-rw-r--r--net/qrtr/qrtr.c120
1 files changed, 69 insertions, 51 deletions
diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c
index d85ca7170b8f..82dc83789310 100644
--- a/net/qrtr/qrtr.c
+++ b/net/qrtr/qrtr.c
@@ -97,8 +97,12 @@ struct qrtr_node {
97 struct list_head item; 97 struct list_head item;
98}; 98};
99 99
100static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb); 100static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
101static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb); 101 int type, struct sockaddr_qrtr *from,
102 struct sockaddr_qrtr *to);
103static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,
104 int type, struct sockaddr_qrtr *from,
105 struct sockaddr_qrtr *to);
102 106
103/* Release node resources and free the node. 107/* Release node resources and free the node.
104 * 108 *
@@ -136,10 +140,27 @@ static void qrtr_node_release(struct qrtr_node *node)
136} 140}
137 141
138/* Pass an outgoing packet socket buffer to the endpoint driver. */ 142/* Pass an outgoing packet socket buffer to the endpoint driver. */
139static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb) 143static int qrtr_node_enqueue(struct qrtr_node *node, struct sk_buff *skb,
144 int type, struct sockaddr_qrtr *from,
145 struct sockaddr_qrtr *to)
140{ 146{
147 struct qrtr_hdr *hdr;
148 size_t len = skb->len;
141 int rc = -ENODEV; 149 int rc = -ENODEV;
142 150
151 hdr = skb_push(skb, QRTR_HDR_SIZE);
152 hdr->version = cpu_to_le32(QRTR_PROTO_VER);
153 hdr->type = cpu_to_le32(type);
154 hdr->src_node_id = cpu_to_le32(from->sq_node);
155 hdr->src_port_id = cpu_to_le32(from->sq_port);
156 hdr->dst_node_id = cpu_to_le32(to->sq_node);
157 hdr->dst_port_id = cpu_to_le32(to->sq_port);
158
159 hdr->size = cpu_to_le32(len);
160 hdr->confirm_rx = 0;
161
162 skb_put_padto(skb, ALIGN(len, 4));
163
143 mutex_lock(&node->ep_lock); 164 mutex_lock(&node->ep_lock);
144 if (node->ep) 165 if (node->ep)
145 rc = node->ep->xmit(node->ep, skb); 166 rc = node->ep->xmit(node->ep, skb);
@@ -237,23 +258,13 @@ EXPORT_SYMBOL_GPL(qrtr_endpoint_post);
237static struct sk_buff *qrtr_alloc_ctrl_packet(u32 type, size_t pkt_len, 258static struct sk_buff *qrtr_alloc_ctrl_packet(u32 type, size_t pkt_len,
238 u32 src_node, u32 dst_node) 259 u32 src_node, u32 dst_node)
239{ 260{
240 struct qrtr_hdr *hdr;
241 struct sk_buff *skb; 261 struct sk_buff *skb;
242 262
243 skb = alloc_skb(QRTR_HDR_SIZE + pkt_len, GFP_KERNEL); 263 skb = alloc_skb(QRTR_HDR_SIZE + pkt_len, GFP_KERNEL);
244 if (!skb) 264 if (!skb)
245 return NULL; 265 return NULL;
246 skb_reset_transport_header(skb);
247 266
248 hdr = skb_put(skb, QRTR_HDR_SIZE); 267 skb_reserve(skb, QRTR_HDR_SIZE);
249 hdr->version = cpu_to_le32(QRTR_PROTO_VER);
250 hdr->type = cpu_to_le32(type);
251 hdr->src_node_id = cpu_to_le32(src_node);
252 hdr->src_port_id = cpu_to_le32(QRTR_PORT_CTRL);
253 hdr->confirm_rx = cpu_to_le32(0);
254 hdr->size = cpu_to_le32(pkt_len);
255 hdr->dst_node_id = cpu_to_le32(dst_node);
256 hdr->dst_port_id = cpu_to_le32(QRTR_PORT_CTRL);
257 268
258 return skb; 269 return skb;
259} 270}
@@ -326,6 +337,8 @@ static void qrtr_port_put(struct qrtr_sock *ipc);
326static void qrtr_node_rx_work(struct work_struct *work) 337static void qrtr_node_rx_work(struct work_struct *work)
327{ 338{
328 struct qrtr_node *node = container_of(work, struct qrtr_node, work); 339 struct qrtr_node *node = container_of(work, struct qrtr_node, work);
340 struct sockaddr_qrtr dst;
341 struct sockaddr_qrtr src;
329 struct sk_buff *skb; 342 struct sk_buff *skb;
330 343
331 while ((skb = skb_dequeue(&node->rx_queue)) != NULL) { 344 while ((skb = skb_dequeue(&node->rx_queue)) != NULL) {
@@ -341,6 +354,11 @@ static void qrtr_node_rx_work(struct work_struct *work)
341 dst_port = le32_to_cpu(phdr->dst_port_id); 354 dst_port = le32_to_cpu(phdr->dst_port_id);
342 confirm = !!phdr->confirm_rx; 355 confirm = !!phdr->confirm_rx;
343 356
357 src.sq_node = src_node;
358 src.sq_port = le32_to_cpu(phdr->src_port_id);
359 dst.sq_node = dst_node;
360 dst.sq_port = dst_port;
361
344 qrtr_node_assign(node, src_node); 362 qrtr_node_assign(node, src_node);
345 363
346 ipc = qrtr_port_lookup(dst_port); 364 ipc = qrtr_port_lookup(dst_port);
@@ -357,7 +375,9 @@ static void qrtr_node_rx_work(struct work_struct *work)
357 skb = qrtr_alloc_resume_tx(dst_node, node->nid, dst_port); 375 skb = qrtr_alloc_resume_tx(dst_node, node->nid, dst_port);
358 if (!skb) 376 if (!skb)
359 break; 377 break;
360 if (qrtr_node_enqueue(node, skb)) 378
379 if (qrtr_node_enqueue(node, skb, QRTR_TYPE_RESUME_TX,
380 &dst, &src))
361 break; 381 break;
362 } 382 }
363 } 383 }
@@ -407,6 +427,8 @@ EXPORT_SYMBOL_GPL(qrtr_endpoint_register);
407void qrtr_endpoint_unregister(struct qrtr_endpoint *ep) 427void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
408{ 428{
409 struct qrtr_node *node = ep->node; 429 struct qrtr_node *node = ep->node;
430 struct sockaddr_qrtr src = {AF_QIPCRTR, node->nid, QRTR_PORT_CTRL};
431 struct sockaddr_qrtr dst = {AF_QIPCRTR, qrtr_local_nid, QRTR_PORT_CTRL};
410 struct sk_buff *skb; 432 struct sk_buff *skb;
411 433
412 mutex_lock(&node->ep_lock); 434 mutex_lock(&node->ep_lock);
@@ -416,7 +438,7 @@ void qrtr_endpoint_unregister(struct qrtr_endpoint *ep)
416 /* Notify the local controller about the event */ 438 /* Notify the local controller about the event */
417 skb = qrtr_alloc_local_bye(node->nid); 439 skb = qrtr_alloc_local_bye(node->nid);
418 if (skb) 440 if (skb)
419 qrtr_local_enqueue(NULL, skb); 441 qrtr_local_enqueue(NULL, skb, QRTR_TYPE_BYE, &src, &dst);
420 442
421 qrtr_node_release(node); 443 qrtr_node_release(node);
422 ep->node = NULL; 444 ep->node = NULL;
@@ -454,11 +476,17 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
454{ 476{
455 struct sk_buff *skb; 477 struct sk_buff *skb;
456 int port = ipc->us.sq_port; 478 int port = ipc->us.sq_port;
479 struct sockaddr_qrtr to;
480
481 to.sq_family = AF_QIPCRTR;
482 to.sq_node = QRTR_NODE_BCAST;
483 to.sq_port = QRTR_PORT_CTRL;
457 484
458 skb = qrtr_alloc_del_client(&ipc->us); 485 skb = qrtr_alloc_del_client(&ipc->us);
459 if (skb) { 486 if (skb) {
460 skb_set_owner_w(skb, &ipc->sk); 487 skb_set_owner_w(skb, &ipc->sk);
461 qrtr_bcast_enqueue(NULL, skb); 488 qrtr_bcast_enqueue(NULL, skb, QRTR_TYPE_DEL_CLIENT, &ipc->us,
489 &to);
462 } 490 }
463 491
464 if (port == QRTR_PORT_CTRL) 492 if (port == QRTR_PORT_CTRL)
@@ -606,19 +634,25 @@ static int qrtr_bind(struct socket *sock, struct sockaddr *saddr, int len)
606} 634}
607 635
608/* Queue packet to local peer socket. */ 636/* Queue packet to local peer socket. */
609static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb) 637static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb,
638 int type, struct sockaddr_qrtr *from,
639 struct sockaddr_qrtr *to)
610{ 640{
611 const struct qrtr_hdr *phdr;
612 struct qrtr_sock *ipc; 641 struct qrtr_sock *ipc;
642 struct qrtr_hdr *phdr;
613 643
614 phdr = (const struct qrtr_hdr *)skb_transport_header(skb); 644 ipc = qrtr_port_lookup(to->sq_port);
615
616 ipc = qrtr_port_lookup(le32_to_cpu(phdr->dst_port_id));
617 if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */ 645 if (!ipc || &ipc->sk == skb->sk) { /* do not send to self */
618 kfree_skb(skb); 646 kfree_skb(skb);
619 return -ENODEV; 647 return -ENODEV;
620 } 648 }
621 649
650 phdr = skb_push(skb, QRTR_HDR_SIZE);
651 skb_reset_transport_header(skb);
652
653 phdr->src_node_id = cpu_to_le32(from->sq_node);
654 phdr->src_port_id = cpu_to_le32(from->sq_port);
655
622 if (sock_queue_rcv_skb(&ipc->sk, skb)) { 656 if (sock_queue_rcv_skb(&ipc->sk, skb)) {
623 qrtr_port_put(ipc); 657 qrtr_port_put(ipc);
624 kfree_skb(skb); 658 kfree_skb(skb);
@@ -631,7 +665,9 @@ static int qrtr_local_enqueue(struct qrtr_node *node, struct sk_buff *skb)
631} 665}
632 666
633/* Queue packet for broadcast. */ 667/* Queue packet for broadcast. */
634static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb) 668static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb,
669 int type, struct sockaddr_qrtr *from,
670 struct sockaddr_qrtr *to)
635{ 671{
636 struct sk_buff *skbn; 672 struct sk_buff *skbn;
637 673
@@ -641,11 +677,11 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb)
641 if (!skbn) 677 if (!skbn)
642 break; 678 break;
643 skb_set_owner_w(skbn, skb->sk); 679 skb_set_owner_w(skbn, skb->sk);
644 qrtr_node_enqueue(node, skbn); 680 qrtr_node_enqueue(node, skbn, type, from, to);
645 } 681 }
646 mutex_unlock(&qrtr_node_lock); 682 mutex_unlock(&qrtr_node_lock);
647 683
648 qrtr_local_enqueue(node, skb); 684 qrtr_local_enqueue(node, skb, type, from, to);
649 685
650 return 0; 686 return 0;
651} 687}
@@ -653,13 +689,14 @@ static int qrtr_bcast_enqueue(struct qrtr_node *node, struct sk_buff *skb)
653static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) 689static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
654{ 690{
655 DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name); 691 DECLARE_SOCKADDR(struct sockaddr_qrtr *, addr, msg->msg_name);
656 int (*enqueue_fn)(struct qrtr_node *, struct sk_buff *); 692 int (*enqueue_fn)(struct qrtr_node *, struct sk_buff *, int,
693 struct sockaddr_qrtr *, struct sockaddr_qrtr *);
657 struct qrtr_sock *ipc = qrtr_sk(sock->sk); 694 struct qrtr_sock *ipc = qrtr_sk(sock->sk);
658 struct sock *sk = sock->sk; 695 struct sock *sk = sock->sk;
659 struct qrtr_node *node; 696 struct qrtr_node *node;
660 struct qrtr_hdr *hdr;
661 struct sk_buff *skb; 697 struct sk_buff *skb;
662 size_t plen; 698 size_t plen;
699 u32 type = QRTR_TYPE_DATA;
663 int rc; 700 int rc;
664 701
665 if (msg->msg_flags & ~(MSG_DONTWAIT)) 702 if (msg->msg_flags & ~(MSG_DONTWAIT))
@@ -713,32 +750,14 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
713 if (!skb) 750 if (!skb)
714 goto out_node; 751 goto out_node;
715 752
716 skb_reset_transport_header(skb); 753 skb_reserve(skb, QRTR_HDR_SIZE);
717 skb_put(skb, len + QRTR_HDR_SIZE);
718
719 hdr = (struct qrtr_hdr *)skb_transport_header(skb);
720 hdr->version = cpu_to_le32(QRTR_PROTO_VER);
721 hdr->src_node_id = cpu_to_le32(ipc->us.sq_node);
722 hdr->src_port_id = cpu_to_le32(ipc->us.sq_port);
723 hdr->confirm_rx = cpu_to_le32(0);
724 hdr->size = cpu_to_le32(len);
725 hdr->dst_node_id = cpu_to_le32(addr->sq_node);
726 hdr->dst_port_id = cpu_to_le32(addr->sq_port);
727 754
728 rc = skb_copy_datagram_from_iter(skb, QRTR_HDR_SIZE, 755 rc = memcpy_from_msg(skb_put(skb, len), msg, len);
729 &msg->msg_iter, len);
730 if (rc) { 756 if (rc) {
731 kfree_skb(skb); 757 kfree_skb(skb);
732 goto out_node; 758 goto out_node;
733 } 759 }
734 760
735 if (plen != len) {
736 rc = skb_pad(skb, plen - len);
737 if (rc)
738 goto out_node;
739 skb_put(skb, plen - len);
740 }
741
742 if (ipc->us.sq_port == QRTR_PORT_CTRL) { 761 if (ipc->us.sq_port == QRTR_PORT_CTRL) {
743 if (len < 4) { 762 if (len < 4) {
744 rc = -EINVAL; 763 rc = -EINVAL;
@@ -747,12 +766,11 @@ static int qrtr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
747 } 766 }
748 767
749 /* control messages already require the type as 'command' */ 768 /* control messages already require the type as 'command' */
750 skb_copy_bits(skb, QRTR_HDR_SIZE, &hdr->type, 4); 769 skb_copy_bits(skb, 0, &type, 4);
751 } else { 770 type = le32_to_cpu(type);
752 hdr->type = cpu_to_le32(QRTR_TYPE_DATA);
753 } 771 }
754 772
755 rc = enqueue_fn(node, skb); 773 rc = enqueue_fn(node, skb, type, &ipc->us, addr);
756 if (rc >= 0) 774 if (rc >= 0)
757 rc = len; 775 rc = len;
758 776