1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (c) 2015, Sony Mobile Communications Inc.
4 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
5 * Copyright (c) 2020, Linaro Ltd.
8 #include <linux/module.h>
9 #include <linux/qrtr.h>
10 #include <linux/workqueue.h>
15 #define CREATE_TRACE_POINTS
16 #include <trace/events/qrtr.h>
18 static RADIX_TREE(nodes
, GFP_KERNEL
);
22 struct sockaddr_qrtr bcast_sq
;
23 struct list_head lookups
;
24 struct workqueue_struct
*workqueue
;
25 struct work_struct work
;
29 static const char * const qrtr_ctrl_pkt_strings
[] = {
30 [QRTR_TYPE_HELLO
] = "hello",
31 [QRTR_TYPE_BYE
] = "bye",
32 [QRTR_TYPE_NEW_SERVER
] = "new-server",
33 [QRTR_TYPE_DEL_SERVER
] = "del-server",
34 [QRTR_TYPE_DEL_CLIENT
] = "del-client",
35 [QRTR_TYPE_RESUME_TX
] = "resume-tx",
36 [QRTR_TYPE_EXIT
] = "exit",
37 [QRTR_TYPE_PING
] = "ping",
38 [QRTR_TYPE_NEW_LOOKUP
] = "new-lookup",
39 [QRTR_TYPE_DEL_LOOKUP
] = "del-lookup",
42 struct qrtr_server_filter
{
44 unsigned int instance
;
50 unsigned int instance
;
52 struct sockaddr_qrtr sq
;
58 unsigned int instance
;
68 struct radix_tree_root servers
;
71 static struct qrtr_node
*node_get(unsigned int node_id
)
73 struct qrtr_node
*node
;
75 node
= radix_tree_lookup(&nodes
, node_id
);
79 /* If node didn't exist, allocate and insert it to the tree */
80 node
= kzalloc(sizeof(*node
), GFP_KERNEL
);
86 radix_tree_insert(&nodes
, node_id
, node
);
91 static int server_match(const struct qrtr_server
*srv
,
92 const struct qrtr_server_filter
*f
)
94 unsigned int ifilter
= f
->ifilter
;
96 if (f
->service
!= 0 && srv
->service
!= f
->service
)
98 if (!ifilter
&& f
->instance
)
101 return (srv
->instance
& ifilter
) == f
->instance
;
104 static int service_announce_new(struct sockaddr_qrtr
*dest
,
105 struct qrtr_server
*srv
)
107 struct qrtr_ctrl_pkt pkt
;
108 struct msghdr msg
= { };
111 trace_qrtr_ns_service_announce_new(srv
->service
, srv
->instance
,
112 srv
->node
, srv
->port
);
115 iv
.iov_len
= sizeof(pkt
);
117 memset(&pkt
, 0, sizeof(pkt
));
118 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_NEW_SERVER
);
119 pkt
.server
.service
= cpu_to_le32(srv
->service
);
120 pkt
.server
.instance
= cpu_to_le32(srv
->instance
);
121 pkt
.server
.node
= cpu_to_le32(srv
->node
);
122 pkt
.server
.port
= cpu_to_le32(srv
->port
);
124 msg
.msg_name
= (struct sockaddr
*)dest
;
125 msg
.msg_namelen
= sizeof(*dest
);
127 return kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
130 static int service_announce_del(struct sockaddr_qrtr
*dest
,
131 struct qrtr_server
*srv
)
133 struct qrtr_ctrl_pkt pkt
;
134 struct msghdr msg
= { };
138 trace_qrtr_ns_service_announce_del(srv
->service
, srv
->instance
,
139 srv
->node
, srv
->port
);
142 iv
.iov_len
= sizeof(pkt
);
144 memset(&pkt
, 0, sizeof(pkt
));
145 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_DEL_SERVER
);
146 pkt
.server
.service
= cpu_to_le32(srv
->service
);
147 pkt
.server
.instance
= cpu_to_le32(srv
->instance
);
148 pkt
.server
.node
= cpu_to_le32(srv
->node
);
149 pkt
.server
.port
= cpu_to_le32(srv
->port
);
151 msg
.msg_name
= (struct sockaddr
*)dest
;
152 msg
.msg_namelen
= sizeof(*dest
);
154 ret
= kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
156 pr_err("failed to announce del service\n");
161 static void lookup_notify(struct sockaddr_qrtr
*to
, struct qrtr_server
*srv
,
164 struct qrtr_ctrl_pkt pkt
;
165 struct msghdr msg
= { };
170 iv
.iov_len
= sizeof(pkt
);
172 memset(&pkt
, 0, sizeof(pkt
));
173 pkt
.cmd
= new ? cpu_to_le32(QRTR_TYPE_NEW_SERVER
) :
174 cpu_to_le32(QRTR_TYPE_DEL_SERVER
);
176 pkt
.server
.service
= cpu_to_le32(srv
->service
);
177 pkt
.server
.instance
= cpu_to_le32(srv
->instance
);
178 pkt
.server
.node
= cpu_to_le32(srv
->node
);
179 pkt
.server
.port
= cpu_to_le32(srv
->port
);
182 msg
.msg_name
= (struct sockaddr
*)to
;
183 msg
.msg_namelen
= sizeof(*to
);
185 ret
= kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
187 pr_err("failed to send lookup notification\n");
190 static int announce_servers(struct sockaddr_qrtr
*sq
)
192 struct radix_tree_iter iter
;
193 struct qrtr_server
*srv
;
194 struct qrtr_node
*node
;
198 node
= node_get(qrtr_ns
.local_node
);
203 /* Announce the list of servers registered in this node */
204 radix_tree_for_each_slot(slot
, &node
->servers
, &iter
, 0) {
205 srv
= radix_tree_deref_slot(slot
);
208 if (radix_tree_deref_retry(srv
)) {
209 slot
= radix_tree_iter_retry(&iter
);
212 slot
= radix_tree_iter_resume(slot
, &iter
);
215 ret
= service_announce_new(sq
, srv
);
217 pr_err("failed to announce new service\n");
229 static struct qrtr_server
*server_add(unsigned int service
,
230 unsigned int instance
,
231 unsigned int node_id
,
234 struct qrtr_server
*srv
;
235 struct qrtr_server
*old
;
236 struct qrtr_node
*node
;
238 if (!service
|| !port
)
241 srv
= kzalloc(sizeof(*srv
), GFP_KERNEL
);
245 srv
->service
= service
;
246 srv
->instance
= instance
;
250 node
= node_get(node_id
);
254 /* Delete the old server on the same port */
255 old
= radix_tree_lookup(&node
->servers
, port
);
257 radix_tree_delete(&node
->servers
, port
);
261 radix_tree_insert(&node
->servers
, port
, srv
);
263 trace_qrtr_ns_server_add(srv
->service
, srv
->instance
,
264 srv
->node
, srv
->port
);
273 static int server_del(struct qrtr_node
*node
, unsigned int port
)
275 struct qrtr_lookup
*lookup
;
276 struct qrtr_server
*srv
;
277 struct list_head
*li
;
279 srv
= radix_tree_lookup(&node
->servers
, port
);
283 radix_tree_delete(&node
->servers
, port
);
285 /* Broadcast the removal of local servers */
286 if (srv
->node
== qrtr_ns
.local_node
)
287 service_announce_del(&qrtr_ns
.bcast_sq
, srv
);
289 /* Announce the service's disappearance to observers */
290 list_for_each(li
, &qrtr_ns
.lookups
) {
291 lookup
= container_of(li
, struct qrtr_lookup
, li
);
292 if (lookup
->service
&& lookup
->service
!= srv
->service
)
294 if (lookup
->instance
&& lookup
->instance
!= srv
->instance
)
297 lookup_notify(&lookup
->sq
, srv
, false);
305 static int say_hello(struct sockaddr_qrtr
*dest
)
307 struct qrtr_ctrl_pkt pkt
;
308 struct msghdr msg
= { };
313 iv
.iov_len
= sizeof(pkt
);
315 memset(&pkt
, 0, sizeof(pkt
));
316 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_HELLO
);
318 msg
.msg_name
= (struct sockaddr
*)dest
;
319 msg
.msg_namelen
= sizeof(*dest
);
321 ret
= kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
323 pr_err("failed to send hello msg\n");
328 /* Announce the list of servers registered on the local node */
329 static int ctrl_cmd_hello(struct sockaddr_qrtr
*sq
)
337 return announce_servers(sq
);
340 static int ctrl_cmd_bye(struct sockaddr_qrtr
*from
)
342 struct qrtr_node
*local_node
;
343 struct radix_tree_iter iter
;
344 struct qrtr_ctrl_pkt pkt
;
345 struct qrtr_server
*srv
;
346 struct sockaddr_qrtr sq
;
347 struct msghdr msg
= { };
348 struct qrtr_node
*node
;
354 iv
.iov_len
= sizeof(pkt
);
356 node
= node_get(from
->sq_node
);
361 /* Advertise removal of this client to all servers of remote node */
362 radix_tree_for_each_slot(slot
, &node
->servers
, &iter
, 0) {
363 srv
= radix_tree_deref_slot(slot
);
366 if (radix_tree_deref_retry(srv
)) {
367 slot
= radix_tree_iter_retry(&iter
);
370 slot
= radix_tree_iter_resume(slot
, &iter
);
372 server_del(node
, srv
->port
);
377 /* Advertise the removal of this client to all local servers */
378 local_node
= node_get(qrtr_ns
.local_node
);
382 memset(&pkt
, 0, sizeof(pkt
));
383 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_BYE
);
384 pkt
.client
.node
= cpu_to_le32(from
->sq_node
);
387 radix_tree_for_each_slot(slot
, &local_node
->servers
, &iter
, 0) {
388 srv
= radix_tree_deref_slot(slot
);
391 if (radix_tree_deref_retry(srv
)) {
392 slot
= radix_tree_iter_retry(&iter
);
395 slot
= radix_tree_iter_resume(slot
, &iter
);
398 sq
.sq_family
= AF_QIPCRTR
;
399 sq
.sq_node
= srv
->node
;
400 sq
.sq_port
= srv
->port
;
402 msg
.msg_name
= (struct sockaddr
*)&sq
;
403 msg
.msg_namelen
= sizeof(sq
);
405 ret
= kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
407 pr_err("failed to send bye cmd\n");
418 static int ctrl_cmd_del_client(struct sockaddr_qrtr
*from
,
419 unsigned int node_id
, unsigned int port
)
421 struct qrtr_node
*local_node
;
422 struct radix_tree_iter iter
;
423 struct qrtr_lookup
*lookup
;
424 struct qrtr_ctrl_pkt pkt
;
425 struct msghdr msg
= { };
426 struct qrtr_server
*srv
;
427 struct sockaddr_qrtr sq
;
428 struct qrtr_node
*node
;
429 struct list_head
*tmp
;
430 struct list_head
*li
;
436 iv
.iov_len
= sizeof(pkt
);
438 /* Don't accept spoofed messages */
439 if (from
->sq_node
!= node_id
)
442 /* Local DEL_CLIENT messages comes from the port being closed */
443 if (from
->sq_node
== qrtr_ns
.local_node
&& from
->sq_port
!= port
)
446 /* Remove any lookups by this client */
447 list_for_each_safe(li
, tmp
, &qrtr_ns
.lookups
) {
448 lookup
= container_of(li
, struct qrtr_lookup
, li
);
449 if (lookup
->sq
.sq_node
!= node_id
)
451 if (lookup
->sq
.sq_port
!= port
)
454 list_del(&lookup
->li
);
458 /* Remove the server belonging to this port */
459 node
= node_get(node_id
);
461 server_del(node
, port
);
463 /* Advertise the removal of this client to all local servers */
464 local_node
= node_get(qrtr_ns
.local_node
);
468 memset(&pkt
, 0, sizeof(pkt
));
469 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_DEL_CLIENT
);
470 pkt
.client
.node
= cpu_to_le32(node_id
);
471 pkt
.client
.port
= cpu_to_le32(port
);
474 radix_tree_for_each_slot(slot
, &local_node
->servers
, &iter
, 0) {
475 srv
= radix_tree_deref_slot(slot
);
478 if (radix_tree_deref_retry(srv
)) {
479 slot
= radix_tree_iter_retry(&iter
);
482 slot
= radix_tree_iter_resume(slot
, &iter
);
485 sq
.sq_family
= AF_QIPCRTR
;
486 sq
.sq_node
= srv
->node
;
487 sq
.sq_port
= srv
->port
;
489 msg
.msg_name
= (struct sockaddr
*)&sq
;
490 msg
.msg_namelen
= sizeof(sq
);
492 ret
= kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
494 pr_err("failed to send del client cmd\n");
505 static int ctrl_cmd_new_server(struct sockaddr_qrtr
*from
,
506 unsigned int service
, unsigned int instance
,
507 unsigned int node_id
, unsigned int port
)
509 struct qrtr_lookup
*lookup
;
510 struct qrtr_server
*srv
;
511 struct list_head
*li
;
514 /* Ignore specified node and port for local servers */
515 if (from
->sq_node
== qrtr_ns
.local_node
) {
516 node_id
= from
->sq_node
;
517 port
= from
->sq_port
;
520 srv
= server_add(service
, instance
, node_id
, port
);
524 if (srv
->node
== qrtr_ns
.local_node
) {
525 ret
= service_announce_new(&qrtr_ns
.bcast_sq
, srv
);
527 pr_err("failed to announce new service\n");
532 /* Notify any potential lookups about the new server */
533 list_for_each(li
, &qrtr_ns
.lookups
) {
534 lookup
= container_of(li
, struct qrtr_lookup
, li
);
535 if (lookup
->service
&& lookup
->service
!= service
)
537 if (lookup
->instance
&& lookup
->instance
!= instance
)
540 lookup_notify(&lookup
->sq
, srv
, true);
546 static int ctrl_cmd_del_server(struct sockaddr_qrtr
*from
,
547 unsigned int service
, unsigned int instance
,
548 unsigned int node_id
, unsigned int port
)
550 struct qrtr_node
*node
;
552 /* Ignore specified node and port for local servers*/
553 if (from
->sq_node
== qrtr_ns
.local_node
) {
554 node_id
= from
->sq_node
;
555 port
= from
->sq_port
;
558 /* Local servers may only unregister themselves */
559 if (from
->sq_node
== qrtr_ns
.local_node
&& from
->sq_port
!= port
)
562 node
= node_get(node_id
);
566 return server_del(node
, port
);
569 static int ctrl_cmd_new_lookup(struct sockaddr_qrtr
*from
,
570 unsigned int service
, unsigned int instance
)
572 struct radix_tree_iter node_iter
;
573 struct qrtr_server_filter filter
;
574 struct radix_tree_iter srv_iter
;
575 struct qrtr_lookup
*lookup
;
576 struct qrtr_node
*node
;
577 void __rcu
**node_slot
;
578 void __rcu
**srv_slot
;
580 /* Accept only local observers */
581 if (from
->sq_node
!= qrtr_ns
.local_node
)
584 lookup
= kzalloc(sizeof(*lookup
), GFP_KERNEL
);
589 lookup
->service
= service
;
590 lookup
->instance
= instance
;
591 list_add_tail(&lookup
->li
, &qrtr_ns
.lookups
);
593 memset(&filter
, 0, sizeof(filter
));
594 filter
.service
= service
;
595 filter
.instance
= instance
;
598 radix_tree_for_each_slot(node_slot
, &nodes
, &node_iter
, 0) {
599 node
= radix_tree_deref_slot(node_slot
);
602 if (radix_tree_deref_retry(node
)) {
603 node_slot
= radix_tree_iter_retry(&node_iter
);
606 node_slot
= radix_tree_iter_resume(node_slot
, &node_iter
);
608 radix_tree_for_each_slot(srv_slot
, &node
->servers
,
610 struct qrtr_server
*srv
;
612 srv
= radix_tree_deref_slot(srv_slot
);
615 if (radix_tree_deref_retry(srv
)) {
616 srv_slot
= radix_tree_iter_retry(&srv_iter
);
620 if (!server_match(srv
, &filter
))
623 srv_slot
= radix_tree_iter_resume(srv_slot
, &srv_iter
);
626 lookup_notify(from
, srv
, true);
632 /* Empty notification, to indicate end of listing */
633 lookup_notify(from
, NULL
, true);
638 static void ctrl_cmd_del_lookup(struct sockaddr_qrtr
*from
,
639 unsigned int service
, unsigned int instance
)
641 struct qrtr_lookup
*lookup
;
642 struct list_head
*tmp
;
643 struct list_head
*li
;
645 list_for_each_safe(li
, tmp
, &qrtr_ns
.lookups
) {
646 lookup
= container_of(li
, struct qrtr_lookup
, li
);
647 if (lookup
->sq
.sq_node
!= from
->sq_node
)
649 if (lookup
->sq
.sq_port
!= from
->sq_port
)
651 if (lookup
->service
!= service
)
653 if (lookup
->instance
&& lookup
->instance
!= instance
)
656 list_del(&lookup
->li
);
661 static void qrtr_ns_worker(struct work_struct
*work
)
663 const struct qrtr_ctrl_pkt
*pkt
;
664 size_t recv_buf_size
= 4096;
665 struct sockaddr_qrtr sq
;
666 struct msghdr msg
= { };
673 msg
.msg_name
= (struct sockaddr
*)&sq
;
674 msg
.msg_namelen
= sizeof(sq
);
676 recv_buf
= kzalloc(recv_buf_size
, GFP_KERNEL
);
681 iv
.iov_base
= recv_buf
;
682 iv
.iov_len
= recv_buf_size
;
684 msglen
= kernel_recvmsg(qrtr_ns
.sock
, &msg
, &iv
, 1,
685 iv
.iov_len
, MSG_DONTWAIT
);
687 if (msglen
== -EAGAIN
)
691 pr_err("error receiving packet: %zd\n", msglen
);
696 cmd
= le32_to_cpu(pkt
->cmd
);
697 if (cmd
< ARRAY_SIZE(qrtr_ctrl_pkt_strings
) &&
698 qrtr_ctrl_pkt_strings
[cmd
])
699 trace_qrtr_ns_message(qrtr_ctrl_pkt_strings
[cmd
],
700 sq
.sq_node
, sq
.sq_port
);
704 case QRTR_TYPE_HELLO
:
705 ret
= ctrl_cmd_hello(&sq
);
708 ret
= ctrl_cmd_bye(&sq
);
710 case QRTR_TYPE_DEL_CLIENT
:
711 ret
= ctrl_cmd_del_client(&sq
,
712 le32_to_cpu(pkt
->client
.node
),
713 le32_to_cpu(pkt
->client
.port
));
715 case QRTR_TYPE_NEW_SERVER
:
716 ret
= ctrl_cmd_new_server(&sq
,
717 le32_to_cpu(pkt
->server
.service
),
718 le32_to_cpu(pkt
->server
.instance
),
719 le32_to_cpu(pkt
->server
.node
),
720 le32_to_cpu(pkt
->server
.port
));
722 case QRTR_TYPE_DEL_SERVER
:
723 ret
= ctrl_cmd_del_server(&sq
,
724 le32_to_cpu(pkt
->server
.service
),
725 le32_to_cpu(pkt
->server
.instance
),
726 le32_to_cpu(pkt
->server
.node
),
727 le32_to_cpu(pkt
->server
.port
));
731 case QRTR_TYPE_RESUME_TX
:
733 case QRTR_TYPE_NEW_LOOKUP
:
734 ret
= ctrl_cmd_new_lookup(&sq
,
735 le32_to_cpu(pkt
->server
.service
),
736 le32_to_cpu(pkt
->server
.instance
));
738 case QRTR_TYPE_DEL_LOOKUP
:
739 ctrl_cmd_del_lookup(&sq
,
740 le32_to_cpu(pkt
->server
.service
),
741 le32_to_cpu(pkt
->server
.instance
));
746 pr_err("failed while handling packet from %d:%d",
747 sq
.sq_node
, sq
.sq_port
);
753 static void qrtr_ns_data_ready(struct sock
*sk
)
755 queue_work(qrtr_ns
.workqueue
, &qrtr_ns
.work
);
758 int qrtr_ns_init(void)
760 struct sockaddr_qrtr sq
;
763 INIT_LIST_HEAD(&qrtr_ns
.lookups
);
764 INIT_WORK(&qrtr_ns
.work
, qrtr_ns_worker
);
766 ret
= sock_create_kern(&init_net
, AF_QIPCRTR
, SOCK_DGRAM
,
767 PF_QIPCRTR
, &qrtr_ns
.sock
);
771 ret
= kernel_getsockname(qrtr_ns
.sock
, (struct sockaddr
*)&sq
);
773 pr_err("failed to get socket name\n");
777 qrtr_ns
.workqueue
= alloc_workqueue("qrtr_ns_handler", WQ_UNBOUND
, 1);
778 if (!qrtr_ns
.workqueue
)
781 qrtr_ns
.sock
->sk
->sk_data_ready
= qrtr_ns_data_ready
;
783 sq
.sq_port
= QRTR_PORT_CTRL
;
784 qrtr_ns
.local_node
= sq
.sq_node
;
786 ret
= kernel_bind(qrtr_ns
.sock
, (struct sockaddr
*)&sq
, sizeof(sq
));
788 pr_err("failed to bind to socket\n");
792 qrtr_ns
.bcast_sq
.sq_family
= AF_QIPCRTR
;
793 qrtr_ns
.bcast_sq
.sq_node
= QRTR_NODE_BCAST
;
794 qrtr_ns
.bcast_sq
.sq_port
= QRTR_PORT_CTRL
;
796 ret
= say_hello(&qrtr_ns
.bcast_sq
);
803 destroy_workqueue(qrtr_ns
.workqueue
);
805 sock_release(qrtr_ns
.sock
);
808 EXPORT_SYMBOL_GPL(qrtr_ns_init
);
810 void qrtr_ns_remove(void)
812 cancel_work_sync(&qrtr_ns
.work
);
813 destroy_workqueue(qrtr_ns
.workqueue
);
814 sock_release(qrtr_ns
.sock
);
816 EXPORT_SYMBOL_GPL(qrtr_ns_remove
);
818 MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
819 MODULE_DESCRIPTION("Qualcomm IPC Router Nameservice");
820 MODULE_LICENSE("Dual BSD/GPL");