Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
0002 /*
0003  * Copyright (c) 2015, Sony Mobile Communications Inc.
0004  * Copyright (c) 2013, The Linux Foundation. All rights reserved.
0005  * Copyright (c) 2020, Linaro Ltd.
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/qrtr.h>
0010 #include <linux/workqueue.h>
0011 #include <net/sock.h>
0012 
0013 #include "qrtr.h"
0014 
0015 #define CREATE_TRACE_POINTS
0016 #include <trace/events/qrtr.h>
0017 
0018 static RADIX_TREE(nodes, GFP_KERNEL);
0019 
0020 static struct {
0021     struct socket *sock;
0022     struct sockaddr_qrtr bcast_sq;
0023     struct list_head lookups;
0024     struct workqueue_struct *workqueue;
0025     struct work_struct work;
0026     int local_node;
0027 } qrtr_ns;
0028 
0029 static const char * const qrtr_ctrl_pkt_strings[] = {
0030     [QRTR_TYPE_HELLO]   = "hello",
0031     [QRTR_TYPE_BYE]     = "bye",
0032     [QRTR_TYPE_NEW_SERVER]  = "new-server",
0033     [QRTR_TYPE_DEL_SERVER]  = "del-server",
0034     [QRTR_TYPE_DEL_CLIENT]  = "del-client",
0035     [QRTR_TYPE_RESUME_TX]   = "resume-tx",
0036     [QRTR_TYPE_EXIT]    = "exit",
0037     [QRTR_TYPE_PING]    = "ping",
0038     [QRTR_TYPE_NEW_LOOKUP]  = "new-lookup",
0039     [QRTR_TYPE_DEL_LOOKUP]  = "del-lookup",
0040 };
0041 
0042 struct qrtr_server_filter {
0043     unsigned int service;
0044     unsigned int instance;
0045     unsigned int ifilter;
0046 };
0047 
0048 struct qrtr_lookup {
0049     unsigned int service;
0050     unsigned int instance;
0051 
0052     struct sockaddr_qrtr sq;
0053     struct list_head li;
0054 };
0055 
0056 struct qrtr_server {
0057     unsigned int service;
0058     unsigned int instance;
0059 
0060     unsigned int node;
0061     unsigned int port;
0062 
0063     struct list_head qli;
0064 };
0065 
0066 struct qrtr_node {
0067     unsigned int id;
0068     struct radix_tree_root servers;
0069 };
0070 
0071 static struct qrtr_node *node_get(unsigned int node_id)
0072 {
0073     struct qrtr_node *node;
0074 
0075     node = radix_tree_lookup(&nodes, node_id);
0076     if (node)
0077         return node;
0078 
0079     /* If node didn't exist, allocate and insert it to the tree */
0080     node = kzalloc(sizeof(*node), GFP_KERNEL);
0081     if (!node)
0082         return NULL;
0083 
0084     node->id = node_id;
0085 
0086     radix_tree_insert(&nodes, node_id, node);
0087 
0088     return node;
0089 }
0090 
0091 static int server_match(const struct qrtr_server *srv,
0092             const struct qrtr_server_filter *f)
0093 {
0094     unsigned int ifilter = f->ifilter;
0095 
0096     if (f->service != 0 && srv->service != f->service)
0097         return 0;
0098     if (!ifilter && f->instance)
0099         ifilter = ~0;
0100 
0101     return (srv->instance & ifilter) == f->instance;
0102 }
0103 
0104 static int service_announce_new(struct sockaddr_qrtr *dest,
0105                 struct qrtr_server *srv)
0106 {
0107     struct qrtr_ctrl_pkt pkt;
0108     struct msghdr msg = { };
0109     struct kvec iv;
0110 
0111     trace_qrtr_ns_service_announce_new(srv->service, srv->instance,
0112                        srv->node, srv->port);
0113 
0114     iv.iov_base = &pkt;
0115     iv.iov_len = sizeof(pkt);
0116 
0117     memset(&pkt, 0, sizeof(pkt));
0118     pkt.cmd = cpu_to_le32(QRTR_TYPE_NEW_SERVER);
0119     pkt.server.service = cpu_to_le32(srv->service);
0120     pkt.server.instance = cpu_to_le32(srv->instance);
0121     pkt.server.node = cpu_to_le32(srv->node);
0122     pkt.server.port = cpu_to_le32(srv->port);
0123 
0124     msg.msg_name = (struct sockaddr *)dest;
0125     msg.msg_namelen = sizeof(*dest);
0126 
0127     return kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
0128 }
0129 
0130 static int service_announce_del(struct sockaddr_qrtr *dest,
0131                 struct qrtr_server *srv)
0132 {
0133     struct qrtr_ctrl_pkt pkt;
0134     struct msghdr msg = { };
0135     struct kvec iv;
0136     int ret;
0137 
0138     trace_qrtr_ns_service_announce_del(srv->service, srv->instance,
0139                        srv->node, srv->port);
0140 
0141     iv.iov_base = &pkt;
0142     iv.iov_len = sizeof(pkt);
0143 
0144     memset(&pkt, 0, sizeof(pkt));
0145     pkt.cmd = cpu_to_le32(QRTR_TYPE_DEL_SERVER);
0146     pkt.server.service = cpu_to_le32(srv->service);
0147     pkt.server.instance = cpu_to_le32(srv->instance);
0148     pkt.server.node = cpu_to_le32(srv->node);
0149     pkt.server.port = cpu_to_le32(srv->port);
0150 
0151     msg.msg_name = (struct sockaddr *)dest;
0152     msg.msg_namelen = sizeof(*dest);
0153 
0154     ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
0155     if (ret < 0)
0156         pr_err("failed to announce del service\n");
0157 
0158     return ret;
0159 }
0160 
0161 static void lookup_notify(struct sockaddr_qrtr *to, struct qrtr_server *srv,
0162               bool new)
0163 {
0164     struct qrtr_ctrl_pkt pkt;
0165     struct msghdr msg = { };
0166     struct kvec iv;
0167     int ret;
0168 
0169     iv.iov_base = &pkt;
0170     iv.iov_len = sizeof(pkt);
0171 
0172     memset(&pkt, 0, sizeof(pkt));
0173     pkt.cmd = new ? cpu_to_le32(QRTR_TYPE_NEW_SERVER) :
0174             cpu_to_le32(QRTR_TYPE_DEL_SERVER);
0175     if (srv) {
0176         pkt.server.service = cpu_to_le32(srv->service);
0177         pkt.server.instance = cpu_to_le32(srv->instance);
0178         pkt.server.node = cpu_to_le32(srv->node);
0179         pkt.server.port = cpu_to_le32(srv->port);
0180     }
0181 
0182     msg.msg_name = (struct sockaddr *)to;
0183     msg.msg_namelen = sizeof(*to);
0184 
0185     ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
0186     if (ret < 0)
0187         pr_err("failed to send lookup notification\n");
0188 }
0189 
0190 static int announce_servers(struct sockaddr_qrtr *sq)
0191 {
0192     struct radix_tree_iter iter;
0193     struct qrtr_server *srv;
0194     struct qrtr_node *node;
0195     void __rcu **slot;
0196     int ret;
0197 
0198     node = node_get(qrtr_ns.local_node);
0199     if (!node)
0200         return 0;
0201 
0202     rcu_read_lock();
0203     /* Announce the list of servers registered in this node */
0204     radix_tree_for_each_slot(slot, &node->servers, &iter, 0) {
0205         srv = radix_tree_deref_slot(slot);
0206         if (!srv)
0207             continue;
0208         if (radix_tree_deref_retry(srv)) {
0209             slot = radix_tree_iter_retry(&iter);
0210             continue;
0211         }
0212         slot = radix_tree_iter_resume(slot, &iter);
0213         rcu_read_unlock();
0214 
0215         ret = service_announce_new(sq, srv);
0216         if (ret < 0) {
0217             pr_err("failed to announce new service\n");
0218             return ret;
0219         }
0220 
0221         rcu_read_lock();
0222     }
0223 
0224     rcu_read_unlock();
0225 
0226     return 0;
0227 }
0228 
0229 static struct qrtr_server *server_add(unsigned int service,
0230                       unsigned int instance,
0231                       unsigned int node_id,
0232                       unsigned int port)
0233 {
0234     struct qrtr_server *srv;
0235     struct qrtr_server *old;
0236     struct qrtr_node *node;
0237 
0238     if (!service || !port)
0239         return NULL;
0240 
0241     srv = kzalloc(sizeof(*srv), GFP_KERNEL);
0242     if (!srv)
0243         return NULL;
0244 
0245     srv->service = service;
0246     srv->instance = instance;
0247     srv->node = node_id;
0248     srv->port = port;
0249 
0250     node = node_get(node_id);
0251     if (!node)
0252         goto err;
0253 
0254     /* Delete the old server on the same port */
0255     old = radix_tree_lookup(&node->servers, port);
0256     if (old) {
0257         radix_tree_delete(&node->servers, port);
0258         kfree(old);
0259     }
0260 
0261     radix_tree_insert(&node->servers, port, srv);
0262 
0263     trace_qrtr_ns_server_add(srv->service, srv->instance,
0264                  srv->node, srv->port);
0265 
0266     return srv;
0267 
0268 err:
0269     kfree(srv);
0270     return NULL;
0271 }
0272 
0273 static int server_del(struct qrtr_node *node, unsigned int port)
0274 {
0275     struct qrtr_lookup *lookup;
0276     struct qrtr_server *srv;
0277     struct list_head *li;
0278 
0279     srv = radix_tree_lookup(&node->servers, port);
0280     if (!srv)
0281         return -ENOENT;
0282 
0283     radix_tree_delete(&node->servers, port);
0284 
0285     /* Broadcast the removal of local servers */
0286     if (srv->node == qrtr_ns.local_node)
0287         service_announce_del(&qrtr_ns.bcast_sq, srv);
0288 
0289     /* Announce the service's disappearance to observers */
0290     list_for_each(li, &qrtr_ns.lookups) {
0291         lookup = container_of(li, struct qrtr_lookup, li);
0292         if (lookup->service && lookup->service != srv->service)
0293             continue;
0294         if (lookup->instance && lookup->instance != srv->instance)
0295             continue;
0296 
0297         lookup_notify(&lookup->sq, srv, false);
0298     }
0299 
0300     kfree(srv);
0301 
0302     return 0;
0303 }
0304 
0305 static int say_hello(struct sockaddr_qrtr *dest)
0306 {
0307     struct qrtr_ctrl_pkt pkt;
0308     struct msghdr msg = { };
0309     struct kvec iv;
0310     int ret;
0311 
0312     iv.iov_base = &pkt;
0313     iv.iov_len = sizeof(pkt);
0314 
0315     memset(&pkt, 0, sizeof(pkt));
0316     pkt.cmd = cpu_to_le32(QRTR_TYPE_HELLO);
0317 
0318     msg.msg_name = (struct sockaddr *)dest;
0319     msg.msg_namelen = sizeof(*dest);
0320 
0321     ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
0322     if (ret < 0)
0323         pr_err("failed to send hello msg\n");
0324 
0325     return ret;
0326 }
0327 
0328 /* Announce the list of servers registered on the local node */
0329 static int ctrl_cmd_hello(struct sockaddr_qrtr *sq)
0330 {
0331     int ret;
0332 
0333     ret = say_hello(sq);
0334     if (ret < 0)
0335         return ret;
0336 
0337     return announce_servers(sq);
0338 }
0339 
0340 static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
0341 {
0342     struct qrtr_node *local_node;
0343     struct radix_tree_iter iter;
0344     struct qrtr_ctrl_pkt pkt;
0345     struct qrtr_server *srv;
0346     struct sockaddr_qrtr sq;
0347     struct msghdr msg = { };
0348     struct qrtr_node *node;
0349     void __rcu **slot;
0350     struct kvec iv;
0351     int ret;
0352 
0353     iv.iov_base = &pkt;
0354     iv.iov_len = sizeof(pkt);
0355 
0356     node = node_get(from->sq_node);
0357     if (!node)
0358         return 0;
0359 
0360     rcu_read_lock();
0361     /* Advertise removal of this client to all servers of remote node */
0362     radix_tree_for_each_slot(slot, &node->servers, &iter, 0) {
0363         srv = radix_tree_deref_slot(slot);
0364         if (!srv)
0365             continue;
0366         if (radix_tree_deref_retry(srv)) {
0367             slot = radix_tree_iter_retry(&iter);
0368             continue;
0369         }
0370         slot = radix_tree_iter_resume(slot, &iter);
0371         rcu_read_unlock();
0372         server_del(node, srv->port);
0373         rcu_read_lock();
0374     }
0375     rcu_read_unlock();
0376 
0377     /* Advertise the removal of this client to all local servers */
0378     local_node = node_get(qrtr_ns.local_node);
0379     if (!local_node)
0380         return 0;
0381 
0382     memset(&pkt, 0, sizeof(pkt));
0383     pkt.cmd = cpu_to_le32(QRTR_TYPE_BYE);
0384     pkt.client.node = cpu_to_le32(from->sq_node);
0385 
0386     rcu_read_lock();
0387     radix_tree_for_each_slot(slot, &local_node->servers, &iter, 0) {
0388         srv = radix_tree_deref_slot(slot);
0389         if (!srv)
0390             continue;
0391         if (radix_tree_deref_retry(srv)) {
0392             slot = radix_tree_iter_retry(&iter);
0393             continue;
0394         }
0395         slot = radix_tree_iter_resume(slot, &iter);
0396         rcu_read_unlock();
0397 
0398         sq.sq_family = AF_QIPCRTR;
0399         sq.sq_node = srv->node;
0400         sq.sq_port = srv->port;
0401 
0402         msg.msg_name = (struct sockaddr *)&sq;
0403         msg.msg_namelen = sizeof(sq);
0404 
0405         ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
0406         if (ret < 0) {
0407             pr_err("failed to send bye cmd\n");
0408             return ret;
0409         }
0410         rcu_read_lock();
0411     }
0412 
0413     rcu_read_unlock();
0414 
0415     return 0;
0416 }
0417 
0418 static int ctrl_cmd_del_client(struct sockaddr_qrtr *from,
0419                    unsigned int node_id, unsigned int port)
0420 {
0421     struct qrtr_node *local_node;
0422     struct radix_tree_iter iter;
0423     struct qrtr_lookup *lookup;
0424     struct qrtr_ctrl_pkt pkt;
0425     struct msghdr msg = { };
0426     struct qrtr_server *srv;
0427     struct sockaddr_qrtr sq;
0428     struct qrtr_node *node;
0429     struct list_head *tmp;
0430     struct list_head *li;
0431     void __rcu **slot;
0432     struct kvec iv;
0433     int ret;
0434 
0435     iv.iov_base = &pkt;
0436     iv.iov_len = sizeof(pkt);
0437 
0438     /* Don't accept spoofed messages */
0439     if (from->sq_node != node_id)
0440         return -EINVAL;
0441 
0442     /* Local DEL_CLIENT messages comes from the port being closed */
0443     if (from->sq_node == qrtr_ns.local_node && from->sq_port != port)
0444         return -EINVAL;
0445 
0446     /* Remove any lookups by this client */
0447     list_for_each_safe(li, tmp, &qrtr_ns.lookups) {
0448         lookup = container_of(li, struct qrtr_lookup, li);
0449         if (lookup->sq.sq_node != node_id)
0450             continue;
0451         if (lookup->sq.sq_port != port)
0452             continue;
0453 
0454         list_del(&lookup->li);
0455         kfree(lookup);
0456     }
0457 
0458     /* Remove the server belonging to this port */
0459     node = node_get(node_id);
0460     if (node)
0461         server_del(node, port);
0462 
0463     /* Advertise the removal of this client to all local servers */
0464     local_node = node_get(qrtr_ns.local_node);
0465     if (!local_node)
0466         return 0;
0467 
0468     memset(&pkt, 0, sizeof(pkt));
0469     pkt.cmd = cpu_to_le32(QRTR_TYPE_DEL_CLIENT);
0470     pkt.client.node = cpu_to_le32(node_id);
0471     pkt.client.port = cpu_to_le32(port);
0472 
0473     rcu_read_lock();
0474     radix_tree_for_each_slot(slot, &local_node->servers, &iter, 0) {
0475         srv = radix_tree_deref_slot(slot);
0476         if (!srv)
0477             continue;
0478         if (radix_tree_deref_retry(srv)) {
0479             slot = radix_tree_iter_retry(&iter);
0480             continue;
0481         }
0482         slot = radix_tree_iter_resume(slot, &iter);
0483         rcu_read_unlock();
0484 
0485         sq.sq_family = AF_QIPCRTR;
0486         sq.sq_node = srv->node;
0487         sq.sq_port = srv->port;
0488 
0489         msg.msg_name = (struct sockaddr *)&sq;
0490         msg.msg_namelen = sizeof(sq);
0491 
0492         ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
0493         if (ret < 0) {
0494             pr_err("failed to send del client cmd\n");
0495             return ret;
0496         }
0497         rcu_read_lock();
0498     }
0499 
0500     rcu_read_unlock();
0501 
0502     return 0;
0503 }
0504 
0505 static int ctrl_cmd_new_server(struct sockaddr_qrtr *from,
0506                    unsigned int service, unsigned int instance,
0507                    unsigned int node_id, unsigned int port)
0508 {
0509     struct qrtr_lookup *lookup;
0510     struct qrtr_server *srv;
0511     struct list_head *li;
0512     int ret = 0;
0513 
0514     /* Ignore specified node and port for local servers */
0515     if (from->sq_node == qrtr_ns.local_node) {
0516         node_id = from->sq_node;
0517         port = from->sq_port;
0518     }
0519 
0520     srv = server_add(service, instance, node_id, port);
0521     if (!srv)
0522         return -EINVAL;
0523 
0524     if (srv->node == qrtr_ns.local_node) {
0525         ret = service_announce_new(&qrtr_ns.bcast_sq, srv);
0526         if (ret < 0) {
0527             pr_err("failed to announce new service\n");
0528             return ret;
0529         }
0530     }
0531 
0532     /* Notify any potential lookups about the new server */
0533     list_for_each(li, &qrtr_ns.lookups) {
0534         lookup = container_of(li, struct qrtr_lookup, li);
0535         if (lookup->service && lookup->service != service)
0536             continue;
0537         if (lookup->instance && lookup->instance != instance)
0538             continue;
0539 
0540         lookup_notify(&lookup->sq, srv, true);
0541     }
0542 
0543     return ret;
0544 }
0545 
0546 static int ctrl_cmd_del_server(struct sockaddr_qrtr *from,
0547                    unsigned int service, unsigned int instance,
0548                    unsigned int node_id, unsigned int port)
0549 {
0550     struct qrtr_node *node;
0551 
0552     /* Ignore specified node and port for local servers*/
0553     if (from->sq_node == qrtr_ns.local_node) {
0554         node_id = from->sq_node;
0555         port = from->sq_port;
0556     }
0557 
0558     /* Local servers may only unregister themselves */
0559     if (from->sq_node == qrtr_ns.local_node && from->sq_port != port)
0560         return -EINVAL;
0561 
0562     node = node_get(node_id);
0563     if (!node)
0564         return -ENOENT;
0565 
0566     return server_del(node, port);
0567 }
0568 
0569 static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from,
0570                    unsigned int service, unsigned int instance)
0571 {
0572     struct radix_tree_iter node_iter;
0573     struct qrtr_server_filter filter;
0574     struct radix_tree_iter srv_iter;
0575     struct qrtr_lookup *lookup;
0576     struct qrtr_node *node;
0577     void __rcu **node_slot;
0578     void __rcu **srv_slot;
0579 
0580     /* Accept only local observers */
0581     if (from->sq_node != qrtr_ns.local_node)
0582         return -EINVAL;
0583 
0584     lookup = kzalloc(sizeof(*lookup), GFP_KERNEL);
0585     if (!lookup)
0586         return -ENOMEM;
0587 
0588     lookup->sq = *from;
0589     lookup->service = service;
0590     lookup->instance = instance;
0591     list_add_tail(&lookup->li, &qrtr_ns.lookups);
0592 
0593     memset(&filter, 0, sizeof(filter));
0594     filter.service = service;
0595     filter.instance = instance;
0596 
0597     rcu_read_lock();
0598     radix_tree_for_each_slot(node_slot, &nodes, &node_iter, 0) {
0599         node = radix_tree_deref_slot(node_slot);
0600         if (!node)
0601             continue;
0602         if (radix_tree_deref_retry(node)) {
0603             node_slot = radix_tree_iter_retry(&node_iter);
0604             continue;
0605         }
0606         node_slot = radix_tree_iter_resume(node_slot, &node_iter);
0607 
0608         radix_tree_for_each_slot(srv_slot, &node->servers,
0609                      &srv_iter, 0) {
0610             struct qrtr_server *srv;
0611 
0612             srv = radix_tree_deref_slot(srv_slot);
0613             if (!srv)
0614                 continue;
0615             if (radix_tree_deref_retry(srv)) {
0616                 srv_slot = radix_tree_iter_retry(&srv_iter);
0617                 continue;
0618             }
0619 
0620             if (!server_match(srv, &filter))
0621                 continue;
0622 
0623             srv_slot = radix_tree_iter_resume(srv_slot, &srv_iter);
0624 
0625             rcu_read_unlock();
0626             lookup_notify(from, srv, true);
0627             rcu_read_lock();
0628         }
0629     }
0630     rcu_read_unlock();
0631 
0632     /* Empty notification, to indicate end of listing */
0633     lookup_notify(from, NULL, true);
0634 
0635     return 0;
0636 }
0637 
0638 static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from,
0639                 unsigned int service, unsigned int instance)
0640 {
0641     struct qrtr_lookup *lookup;
0642     struct list_head *tmp;
0643     struct list_head *li;
0644 
0645     list_for_each_safe(li, tmp, &qrtr_ns.lookups) {
0646         lookup = container_of(li, struct qrtr_lookup, li);
0647         if (lookup->sq.sq_node != from->sq_node)
0648             continue;
0649         if (lookup->sq.sq_port != from->sq_port)
0650             continue;
0651         if (lookup->service != service)
0652             continue;
0653         if (lookup->instance && lookup->instance != instance)
0654             continue;
0655 
0656         list_del(&lookup->li);
0657         kfree(lookup);
0658     }
0659 }
0660 
0661 static void qrtr_ns_worker(struct work_struct *work)
0662 {
0663     const struct qrtr_ctrl_pkt *pkt;
0664     size_t recv_buf_size = 4096;
0665     struct sockaddr_qrtr sq;
0666     struct msghdr msg = { };
0667     unsigned int cmd;
0668     ssize_t msglen;
0669     void *recv_buf;
0670     struct kvec iv;
0671     int ret;
0672 
0673     msg.msg_name = (struct sockaddr *)&sq;
0674     msg.msg_namelen = sizeof(sq);
0675 
0676     recv_buf = kzalloc(recv_buf_size, GFP_KERNEL);
0677     if (!recv_buf)
0678         return;
0679 
0680     for (;;) {
0681         iv.iov_base = recv_buf;
0682         iv.iov_len = recv_buf_size;
0683 
0684         msglen = kernel_recvmsg(qrtr_ns.sock, &msg, &iv, 1,
0685                     iv.iov_len, MSG_DONTWAIT);
0686 
0687         if (msglen == -EAGAIN)
0688             break;
0689 
0690         if (msglen < 0) {
0691             pr_err("error receiving packet: %zd\n", msglen);
0692             break;
0693         }
0694 
0695         pkt = recv_buf;
0696         cmd = le32_to_cpu(pkt->cmd);
0697         if (cmd < ARRAY_SIZE(qrtr_ctrl_pkt_strings) &&
0698             qrtr_ctrl_pkt_strings[cmd])
0699             trace_qrtr_ns_message(qrtr_ctrl_pkt_strings[cmd],
0700                           sq.sq_node, sq.sq_port);
0701 
0702         ret = 0;
0703         switch (cmd) {
0704         case QRTR_TYPE_HELLO:
0705             ret = ctrl_cmd_hello(&sq);
0706             break;
0707         case QRTR_TYPE_BYE:
0708             ret = ctrl_cmd_bye(&sq);
0709             break;
0710         case QRTR_TYPE_DEL_CLIENT:
0711             ret = ctrl_cmd_del_client(&sq,
0712                     le32_to_cpu(pkt->client.node),
0713                     le32_to_cpu(pkt->client.port));
0714             break;
0715         case QRTR_TYPE_NEW_SERVER:
0716             ret = ctrl_cmd_new_server(&sq,
0717                     le32_to_cpu(pkt->server.service),
0718                     le32_to_cpu(pkt->server.instance),
0719                     le32_to_cpu(pkt->server.node),
0720                     le32_to_cpu(pkt->server.port));
0721             break;
0722         case QRTR_TYPE_DEL_SERVER:
0723             ret = ctrl_cmd_del_server(&sq,
0724                      le32_to_cpu(pkt->server.service),
0725                      le32_to_cpu(pkt->server.instance),
0726                      le32_to_cpu(pkt->server.node),
0727                      le32_to_cpu(pkt->server.port));
0728             break;
0729         case QRTR_TYPE_EXIT:
0730         case QRTR_TYPE_PING:
0731         case QRTR_TYPE_RESUME_TX:
0732             break;
0733         case QRTR_TYPE_NEW_LOOKUP:
0734             ret = ctrl_cmd_new_lookup(&sq,
0735                      le32_to_cpu(pkt->server.service),
0736                      le32_to_cpu(pkt->server.instance));
0737             break;
0738         case QRTR_TYPE_DEL_LOOKUP:
0739             ctrl_cmd_del_lookup(&sq,
0740                     le32_to_cpu(pkt->server.service),
0741                     le32_to_cpu(pkt->server.instance));
0742             break;
0743         }
0744 
0745         if (ret < 0)
0746             pr_err("failed while handling packet from %d:%d",
0747                    sq.sq_node, sq.sq_port);
0748     }
0749 
0750     kfree(recv_buf);
0751 }
0752 
0753 static void qrtr_ns_data_ready(struct sock *sk)
0754 {
0755     queue_work(qrtr_ns.workqueue, &qrtr_ns.work);
0756 }
0757 
0758 int qrtr_ns_init(void)
0759 {
0760     struct sockaddr_qrtr sq;
0761     int ret;
0762 
0763     INIT_LIST_HEAD(&qrtr_ns.lookups);
0764     INIT_WORK(&qrtr_ns.work, qrtr_ns_worker);
0765 
0766     ret = sock_create_kern(&init_net, AF_QIPCRTR, SOCK_DGRAM,
0767                    PF_QIPCRTR, &qrtr_ns.sock);
0768     if (ret < 0)
0769         return ret;
0770 
0771     ret = kernel_getsockname(qrtr_ns.sock, (struct sockaddr *)&sq);
0772     if (ret < 0) {
0773         pr_err("failed to get socket name\n");
0774         goto err_sock;
0775     }
0776 
0777     qrtr_ns.workqueue = alloc_workqueue("qrtr_ns_handler", WQ_UNBOUND, 1);
0778     if (!qrtr_ns.workqueue) {
0779         ret = -ENOMEM;
0780         goto err_sock;
0781     }
0782 
0783     qrtr_ns.sock->sk->sk_data_ready = qrtr_ns_data_ready;
0784 
0785     sq.sq_port = QRTR_PORT_CTRL;
0786     qrtr_ns.local_node = sq.sq_node;
0787 
0788     ret = kernel_bind(qrtr_ns.sock, (struct sockaddr *)&sq, sizeof(sq));
0789     if (ret < 0) {
0790         pr_err("failed to bind to socket\n");
0791         goto err_wq;
0792     }
0793 
0794     qrtr_ns.bcast_sq.sq_family = AF_QIPCRTR;
0795     qrtr_ns.bcast_sq.sq_node = QRTR_NODE_BCAST;
0796     qrtr_ns.bcast_sq.sq_port = QRTR_PORT_CTRL;
0797 
0798     ret = say_hello(&qrtr_ns.bcast_sq);
0799     if (ret < 0)
0800         goto err_wq;
0801 
0802     return 0;
0803 
0804 err_wq:
0805     destroy_workqueue(qrtr_ns.workqueue);
0806 err_sock:
0807     sock_release(qrtr_ns.sock);
0808     return ret;
0809 }
0810 EXPORT_SYMBOL_GPL(qrtr_ns_init);
0811 
0812 void qrtr_ns_remove(void)
0813 {
0814     cancel_work_sync(&qrtr_ns.work);
0815     destroy_workqueue(qrtr_ns.workqueue);
0816     sock_release(qrtr_ns.sock);
0817 }
0818 EXPORT_SYMBOL_GPL(qrtr_ns_remove);
0819 
0820 MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
0821 MODULE_DESCRIPTION("Qualcomm IPC Router Nameservice");
0822 MODULE_LICENSE("Dual BSD/GPL");