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 static RADIX_TREE(nodes
, GFP_KERNEL
);
19 struct sockaddr_qrtr bcast_sq
;
20 struct list_head lookups
;
21 struct workqueue_struct
*workqueue
;
22 struct work_struct work
;
26 static const char * const qrtr_ctrl_pkt_strings
[] = {
27 [QRTR_TYPE_HELLO
] = "hello",
28 [QRTR_TYPE_BYE
] = "bye",
29 [QRTR_TYPE_NEW_SERVER
] = "new-server",
30 [QRTR_TYPE_DEL_SERVER
] = "del-server",
31 [QRTR_TYPE_DEL_CLIENT
] = "del-client",
32 [QRTR_TYPE_RESUME_TX
] = "resume-tx",
33 [QRTR_TYPE_EXIT
] = "exit",
34 [QRTR_TYPE_PING
] = "ping",
35 [QRTR_TYPE_NEW_LOOKUP
] = "new-lookup",
36 [QRTR_TYPE_DEL_LOOKUP
] = "del-lookup",
39 struct qrtr_server_filter
{
41 unsigned int instance
;
47 unsigned int instance
;
49 struct sockaddr_qrtr sq
;
55 unsigned int instance
;
65 struct radix_tree_root servers
;
68 static struct qrtr_node
*node_get(unsigned int node_id
)
70 struct qrtr_node
*node
;
72 node
= radix_tree_lookup(&nodes
, node_id
);
76 /* If node didn't exist, allocate and insert it to the tree */
77 node
= kzalloc(sizeof(*node
), GFP_KERNEL
);
83 radix_tree_insert(&nodes
, node_id
, node
);
88 static int server_match(const struct qrtr_server
*srv
,
89 const struct qrtr_server_filter
*f
)
91 unsigned int ifilter
= f
->ifilter
;
93 if (f
->service
!= 0 && srv
->service
!= f
->service
)
95 if (!ifilter
&& f
->instance
)
98 return (srv
->instance
& ifilter
) == f
->instance
;
101 static int service_announce_new(struct sockaddr_qrtr
*dest
,
102 struct qrtr_server
*srv
)
104 struct qrtr_ctrl_pkt pkt
;
105 struct msghdr msg
= { };
108 trace_printk("advertising new server [%d:%x]@[%d:%d]\n",
109 srv
->service
, srv
->instance
, srv
->node
, srv
->port
);
112 iv
.iov_len
= sizeof(pkt
);
114 memset(&pkt
, 0, sizeof(pkt
));
115 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_NEW_SERVER
);
116 pkt
.server
.service
= cpu_to_le32(srv
->service
);
117 pkt
.server
.instance
= cpu_to_le32(srv
->instance
);
118 pkt
.server
.node
= cpu_to_le32(srv
->node
);
119 pkt
.server
.port
= cpu_to_le32(srv
->port
);
121 msg
.msg_name
= (struct sockaddr
*)dest
;
122 msg
.msg_namelen
= sizeof(*dest
);
124 return kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
127 static int service_announce_del(struct sockaddr_qrtr
*dest
,
128 struct qrtr_server
*srv
)
130 struct qrtr_ctrl_pkt pkt
;
131 struct msghdr msg
= { };
135 trace_printk("advertising removal of server [%d:%x]@[%d:%d]\n",
136 srv
->service
, srv
->instance
, srv
->node
, srv
->port
);
139 iv
.iov_len
= sizeof(pkt
);
141 memset(&pkt
, 0, sizeof(pkt
));
142 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_DEL_SERVER
);
143 pkt
.server
.service
= cpu_to_le32(srv
->service
);
144 pkt
.server
.instance
= cpu_to_le32(srv
->instance
);
145 pkt
.server
.node
= cpu_to_le32(srv
->node
);
146 pkt
.server
.port
= cpu_to_le32(srv
->port
);
148 msg
.msg_name
= (struct sockaddr
*)dest
;
149 msg
.msg_namelen
= sizeof(*dest
);
151 ret
= kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
153 pr_err("failed to announce del service\n");
158 static void lookup_notify(struct sockaddr_qrtr
*to
, struct qrtr_server
*srv
,
161 struct qrtr_ctrl_pkt pkt
;
162 struct msghdr msg
= { };
167 iv
.iov_len
= sizeof(pkt
);
169 memset(&pkt
, 0, sizeof(pkt
));
170 pkt
.cmd
= new ? cpu_to_le32(QRTR_TYPE_NEW_SERVER
) :
171 cpu_to_le32(QRTR_TYPE_DEL_SERVER
);
173 pkt
.server
.service
= cpu_to_le32(srv
->service
);
174 pkt
.server
.instance
= cpu_to_le32(srv
->instance
);
175 pkt
.server
.node
= cpu_to_le32(srv
->node
);
176 pkt
.server
.port
= cpu_to_le32(srv
->port
);
179 msg
.msg_name
= (struct sockaddr
*)to
;
180 msg
.msg_namelen
= sizeof(*to
);
182 ret
= kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
184 pr_err("failed to send lookup notification\n");
187 static int announce_servers(struct sockaddr_qrtr
*sq
)
189 struct radix_tree_iter iter
;
190 struct qrtr_server
*srv
;
191 struct qrtr_node
*node
;
195 node
= node_get(qrtr_ns
.local_node
);
199 /* Announce the list of servers registered in this node */
200 radix_tree_for_each_slot(slot
, &node
->servers
, &iter
, 0) {
201 srv
= radix_tree_deref_slot(slot
);
203 ret
= service_announce_new(sq
, srv
);
205 pr_err("failed to announce new service\n");
213 static struct qrtr_server
*server_add(unsigned int service
,
214 unsigned int instance
,
215 unsigned int node_id
,
218 struct qrtr_server
*srv
;
219 struct qrtr_server
*old
;
220 struct qrtr_node
*node
;
222 if (!service
|| !port
)
225 srv
= kzalloc(sizeof(*srv
), GFP_KERNEL
);
229 srv
->service
= service
;
230 srv
->instance
= instance
;
234 node
= node_get(node_id
);
238 /* Delete the old server on the same port */
239 old
= radix_tree_lookup(&node
->servers
, port
);
241 radix_tree_delete(&node
->servers
, port
);
245 radix_tree_insert(&node
->servers
, port
, srv
);
247 trace_printk("add server [%d:%x]@[%d:%d]\n", srv
->service
,
248 srv
->instance
, srv
->node
, srv
->port
);
257 static int server_del(struct qrtr_node
*node
, unsigned int port
)
259 struct qrtr_lookup
*lookup
;
260 struct qrtr_server
*srv
;
261 struct list_head
*li
;
263 srv
= radix_tree_lookup(&node
->servers
, port
);
267 radix_tree_delete(&node
->servers
, port
);
269 /* Broadcast the removal of local servers */
270 if (srv
->node
== qrtr_ns
.local_node
)
271 service_announce_del(&qrtr_ns
.bcast_sq
, srv
);
273 /* Announce the service's disappearance to observers */
274 list_for_each(li
, &qrtr_ns
.lookups
) {
275 lookup
= container_of(li
, struct qrtr_lookup
, li
);
276 if (lookup
->service
&& lookup
->service
!= srv
->service
)
278 if (lookup
->instance
&& lookup
->instance
!= srv
->instance
)
281 lookup_notify(&lookup
->sq
, srv
, false);
289 static int say_hello(struct sockaddr_qrtr
*dest
)
291 struct qrtr_ctrl_pkt pkt
;
292 struct msghdr msg
= { };
297 iv
.iov_len
= sizeof(pkt
);
299 memset(&pkt
, 0, sizeof(pkt
));
300 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_HELLO
);
302 msg
.msg_name
= (struct sockaddr
*)dest
;
303 msg
.msg_namelen
= sizeof(*dest
);
305 ret
= kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
307 pr_err("failed to send hello msg\n");
312 /* Announce the list of servers registered on the local node */
313 static int ctrl_cmd_hello(struct sockaddr_qrtr
*sq
)
321 return announce_servers(sq
);
324 static int ctrl_cmd_bye(struct sockaddr_qrtr
*from
)
326 struct qrtr_node
*local_node
;
327 struct radix_tree_iter iter
;
328 struct qrtr_ctrl_pkt pkt
;
329 struct qrtr_server
*srv
;
330 struct sockaddr_qrtr sq
;
331 struct msghdr msg
= { };
332 struct qrtr_node
*node
;
338 iv
.iov_len
= sizeof(pkt
);
340 node
= node_get(from
->sq_node
);
344 /* Advertise removal of this client to all servers of remote node */
345 radix_tree_for_each_slot(slot
, &node
->servers
, &iter
, 0) {
346 srv
= radix_tree_deref_slot(slot
);
347 server_del(node
, srv
->port
);
350 /* Advertise the removal of this client to all local servers */
351 local_node
= node_get(qrtr_ns
.local_node
);
355 memset(&pkt
, 0, sizeof(pkt
));
356 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_BYE
);
357 pkt
.client
.node
= cpu_to_le32(from
->sq_node
);
359 radix_tree_for_each_slot(slot
, &local_node
->servers
, &iter
, 0) {
360 srv
= radix_tree_deref_slot(slot
);
362 sq
.sq_family
= AF_QIPCRTR
;
363 sq
.sq_node
= srv
->node
;
364 sq
.sq_port
= srv
->port
;
366 msg
.msg_name
= (struct sockaddr
*)&sq
;
367 msg
.msg_namelen
= sizeof(sq
);
369 ret
= kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
371 pr_err("failed to send bye cmd\n");
379 static int ctrl_cmd_del_client(struct sockaddr_qrtr
*from
,
380 unsigned int node_id
, unsigned int port
)
382 struct qrtr_node
*local_node
;
383 struct radix_tree_iter iter
;
384 struct qrtr_lookup
*lookup
;
385 struct qrtr_ctrl_pkt pkt
;
386 struct msghdr msg
= { };
387 struct qrtr_server
*srv
;
388 struct sockaddr_qrtr sq
;
389 struct qrtr_node
*node
;
390 struct list_head
*tmp
;
391 struct list_head
*li
;
397 iv
.iov_len
= sizeof(pkt
);
399 /* Don't accept spoofed messages */
400 if (from
->sq_node
!= node_id
)
403 /* Local DEL_CLIENT messages comes from the port being closed */
404 if (from
->sq_node
== qrtr_ns
.local_node
&& from
->sq_port
!= port
)
407 /* Remove any lookups by this client */
408 list_for_each_safe(li
, tmp
, &qrtr_ns
.lookups
) {
409 lookup
= container_of(li
, struct qrtr_lookup
, li
);
410 if (lookup
->sq
.sq_node
!= node_id
)
412 if (lookup
->sq
.sq_port
!= port
)
415 list_del(&lookup
->li
);
419 /* Remove the server belonging to this port */
420 node
= node_get(node_id
);
422 server_del(node
, port
);
424 /* Advertise the removal of this client to all local servers */
425 local_node
= node_get(qrtr_ns
.local_node
);
429 memset(&pkt
, 0, sizeof(pkt
));
430 pkt
.cmd
= cpu_to_le32(QRTR_TYPE_DEL_CLIENT
);
431 pkt
.client
.node
= cpu_to_le32(node_id
);
432 pkt
.client
.port
= cpu_to_le32(port
);
434 radix_tree_for_each_slot(slot
, &local_node
->servers
, &iter
, 0) {
435 srv
= radix_tree_deref_slot(slot
);
437 sq
.sq_family
= AF_QIPCRTR
;
438 sq
.sq_node
= srv
->node
;
439 sq
.sq_port
= srv
->port
;
441 msg
.msg_name
= (struct sockaddr
*)&sq
;
442 msg
.msg_namelen
= sizeof(sq
);
444 ret
= kernel_sendmsg(qrtr_ns
.sock
, &msg
, &iv
, 1, sizeof(pkt
));
446 pr_err("failed to send del client cmd\n");
454 static int ctrl_cmd_new_server(struct sockaddr_qrtr
*from
,
455 unsigned int service
, unsigned int instance
,
456 unsigned int node_id
, unsigned int port
)
458 struct qrtr_lookup
*lookup
;
459 struct qrtr_server
*srv
;
460 struct list_head
*li
;
463 /* Ignore specified node and port for local servers */
464 if (from
->sq_node
== qrtr_ns
.local_node
) {
465 node_id
= from
->sq_node
;
466 port
= from
->sq_port
;
469 /* Don't accept spoofed messages */
470 if (from
->sq_node
!= node_id
)
473 srv
= server_add(service
, instance
, node_id
, port
);
477 if (srv
->node
== qrtr_ns
.local_node
) {
478 ret
= service_announce_new(&qrtr_ns
.bcast_sq
, srv
);
480 pr_err("failed to announce new service\n");
485 /* Notify any potential lookups about the new server */
486 list_for_each(li
, &qrtr_ns
.lookups
) {
487 lookup
= container_of(li
, struct qrtr_lookup
, li
);
488 if (lookup
->service
&& lookup
->service
!= service
)
490 if (lookup
->instance
&& lookup
->instance
!= instance
)
493 lookup_notify(&lookup
->sq
, srv
, true);
499 static int ctrl_cmd_del_server(struct sockaddr_qrtr
*from
,
500 unsigned int service
, unsigned int instance
,
501 unsigned int node_id
, unsigned int port
)
503 struct qrtr_node
*node
;
505 /* Ignore specified node and port for local servers*/
506 if (from
->sq_node
== qrtr_ns
.local_node
) {
507 node_id
= from
->sq_node
;
508 port
= from
->sq_port
;
511 /* Don't accept spoofed messages */
512 if (from
->sq_node
!= node_id
)
515 /* Local servers may only unregister themselves */
516 if (from
->sq_node
== qrtr_ns
.local_node
&& from
->sq_port
!= port
)
519 node
= node_get(node_id
);
523 return server_del(node
, port
);
526 static int ctrl_cmd_new_lookup(struct sockaddr_qrtr
*from
,
527 unsigned int service
, unsigned int instance
)
529 struct radix_tree_iter node_iter
;
530 struct qrtr_server_filter filter
;
531 struct radix_tree_iter srv_iter
;
532 struct qrtr_lookup
*lookup
;
533 struct qrtr_node
*node
;
534 void __rcu
**node_slot
;
535 void __rcu
**srv_slot
;
537 /* Accept only local observers */
538 if (from
->sq_node
!= qrtr_ns
.local_node
)
541 lookup
= kzalloc(sizeof(*lookup
), GFP_KERNEL
);
546 lookup
->service
= service
;
547 lookup
->instance
= instance
;
548 list_add_tail(&lookup
->li
, &qrtr_ns
.lookups
);
550 memset(&filter
, 0, sizeof(filter
));
551 filter
.service
= service
;
552 filter
.instance
= instance
;
554 radix_tree_for_each_slot(node_slot
, &nodes
, &node_iter
, 0) {
555 node
= radix_tree_deref_slot(node_slot
);
557 radix_tree_for_each_slot(srv_slot
, &node
->servers
,
559 struct qrtr_server
*srv
;
561 srv
= radix_tree_deref_slot(srv_slot
);
562 if (!server_match(srv
, &filter
))
565 lookup_notify(from
, srv
, true);
569 /* Empty notification, to indicate end of listing */
570 lookup_notify(from
, NULL
, true);
575 static void ctrl_cmd_del_lookup(struct sockaddr_qrtr
*from
,
576 unsigned int service
, unsigned int instance
)
578 struct qrtr_lookup
*lookup
;
579 struct list_head
*tmp
;
580 struct list_head
*li
;
582 list_for_each_safe(li
, tmp
, &qrtr_ns
.lookups
) {
583 lookup
= container_of(li
, struct qrtr_lookup
, li
);
584 if (lookup
->sq
.sq_node
!= from
->sq_node
)
586 if (lookup
->sq
.sq_port
!= from
->sq_port
)
588 if (lookup
->service
!= service
)
590 if (lookup
->instance
&& lookup
->instance
!= instance
)
593 list_del(&lookup
->li
);
598 static void qrtr_ns_worker(struct work_struct
*work
)
600 const struct qrtr_ctrl_pkt
*pkt
;
601 size_t recv_buf_size
= 4096;
602 struct sockaddr_qrtr sq
;
603 struct msghdr msg
= { };
610 msg
.msg_name
= (struct sockaddr
*)&sq
;
611 msg
.msg_namelen
= sizeof(sq
);
613 recv_buf
= kzalloc(recv_buf_size
, GFP_KERNEL
);
618 iv
.iov_base
= recv_buf
;
619 iv
.iov_len
= recv_buf_size
;
621 msglen
= kernel_recvmsg(qrtr_ns
.sock
, &msg
, &iv
, 1,
622 iv
.iov_len
, MSG_DONTWAIT
);
624 if (msglen
== -EAGAIN
)
628 pr_err("error receiving packet: %zd\n", msglen
);
633 cmd
= le32_to_cpu(pkt
->cmd
);
634 if (cmd
< ARRAY_SIZE(qrtr_ctrl_pkt_strings
) &&
635 qrtr_ctrl_pkt_strings
[cmd
])
636 trace_printk("%s from %d:%d\n",
637 qrtr_ctrl_pkt_strings
[cmd
], sq
.sq_node
,
642 case QRTR_TYPE_HELLO
:
643 ret
= ctrl_cmd_hello(&sq
);
646 ret
= ctrl_cmd_bye(&sq
);
648 case QRTR_TYPE_DEL_CLIENT
:
649 ret
= ctrl_cmd_del_client(&sq
,
650 le32_to_cpu(pkt
->client
.node
),
651 le32_to_cpu(pkt
->client
.port
));
653 case QRTR_TYPE_NEW_SERVER
:
654 ret
= ctrl_cmd_new_server(&sq
,
655 le32_to_cpu(pkt
->server
.service
),
656 le32_to_cpu(pkt
->server
.instance
),
657 le32_to_cpu(pkt
->server
.node
),
658 le32_to_cpu(pkt
->server
.port
));
660 case QRTR_TYPE_DEL_SERVER
:
661 ret
= ctrl_cmd_del_server(&sq
,
662 le32_to_cpu(pkt
->server
.service
),
663 le32_to_cpu(pkt
->server
.instance
),
664 le32_to_cpu(pkt
->server
.node
),
665 le32_to_cpu(pkt
->server
.port
));
669 case QRTR_TYPE_RESUME_TX
:
671 case QRTR_TYPE_NEW_LOOKUP
:
672 ret
= ctrl_cmd_new_lookup(&sq
,
673 le32_to_cpu(pkt
->server
.service
),
674 le32_to_cpu(pkt
->server
.instance
));
676 case QRTR_TYPE_DEL_LOOKUP
:
677 ctrl_cmd_del_lookup(&sq
,
678 le32_to_cpu(pkt
->server
.service
),
679 le32_to_cpu(pkt
->server
.instance
));
684 pr_err("failed while handling packet from %d:%d",
685 sq
.sq_node
, sq
.sq_port
);
691 static void qrtr_ns_data_ready(struct sock
*sk
)
693 queue_work(qrtr_ns
.workqueue
, &qrtr_ns
.work
);
696 void qrtr_ns_init(void)
698 struct sockaddr_qrtr sq
;
701 INIT_LIST_HEAD(&qrtr_ns
.lookups
);
702 INIT_WORK(&qrtr_ns
.work
, qrtr_ns_worker
);
704 ret
= sock_create_kern(&init_net
, AF_QIPCRTR
, SOCK_DGRAM
,
705 PF_QIPCRTR
, &qrtr_ns
.sock
);
709 ret
= kernel_getsockname(qrtr_ns
.sock
, (struct sockaddr
*)&sq
);
711 pr_err("failed to get socket name\n");
715 qrtr_ns
.workqueue
= alloc_workqueue("qrtr_ns_handler", WQ_UNBOUND
, 1);
716 if (!qrtr_ns
.workqueue
)
719 qrtr_ns
.sock
->sk
->sk_data_ready
= qrtr_ns_data_ready
;
721 sq
.sq_port
= QRTR_PORT_CTRL
;
722 qrtr_ns
.local_node
= sq
.sq_node
;
724 ret
= kernel_bind(qrtr_ns
.sock
, (struct sockaddr
*)&sq
, sizeof(sq
));
726 pr_err("failed to bind to socket\n");
730 qrtr_ns
.bcast_sq
.sq_family
= AF_QIPCRTR
;
731 qrtr_ns
.bcast_sq
.sq_node
= QRTR_NODE_BCAST
;
732 qrtr_ns
.bcast_sq
.sq_port
= QRTR_PORT_CTRL
;
734 ret
= say_hello(&qrtr_ns
.bcast_sq
);
741 destroy_workqueue(qrtr_ns
.workqueue
);
743 sock_release(qrtr_ns
.sock
);
745 EXPORT_SYMBOL_GPL(qrtr_ns_init
);
747 void qrtr_ns_remove(void)
749 cancel_work_sync(&qrtr_ns
.work
);
750 destroy_workqueue(qrtr_ns
.workqueue
);
751 sock_release(qrtr_ns
.sock
);
753 EXPORT_SYMBOL_GPL(qrtr_ns_remove
);
755 MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
756 MODULE_DESCRIPTION("Qualcomm IPC Router Nameservice");
757 MODULE_LICENSE("Dual BSD/GPL");