cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ns.c (18886B)


      1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
      2/*
      3 * Copyright (c) 2015, Sony Mobile Communications Inc.
      4 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
      5 * Copyright (c) 2020, Linaro Ltd.
      6 */
      7
      8#include <linux/module.h>
      9#include <linux/qrtr.h>
     10#include <linux/workqueue.h>
     11#include <net/sock.h>
     12
     13#include "qrtr.h"
     14
     15#define CREATE_TRACE_POINTS
     16#include <trace/events/qrtr.h>
     17
     18static RADIX_TREE(nodes, GFP_KERNEL);
     19
     20static struct {
     21	struct socket *sock;
     22	struct sockaddr_qrtr bcast_sq;
     23	struct list_head lookups;
     24	struct workqueue_struct *workqueue;
     25	struct work_struct work;
     26	int local_node;
     27} qrtr_ns;
     28
     29static 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",
     40};
     41
     42struct qrtr_server_filter {
     43	unsigned int service;
     44	unsigned int instance;
     45	unsigned int ifilter;
     46};
     47
     48struct qrtr_lookup {
     49	unsigned int service;
     50	unsigned int instance;
     51
     52	struct sockaddr_qrtr sq;
     53	struct list_head li;
     54};
     55
     56struct qrtr_server {
     57	unsigned int service;
     58	unsigned int instance;
     59
     60	unsigned int node;
     61	unsigned int port;
     62
     63	struct list_head qli;
     64};
     65
     66struct qrtr_node {
     67	unsigned int id;
     68	struct radix_tree_root servers;
     69};
     70
     71static struct qrtr_node *node_get(unsigned int node_id)
     72{
     73	struct qrtr_node *node;
     74
     75	node = radix_tree_lookup(&nodes, node_id);
     76	if (node)
     77		return node;
     78
     79	/* If node didn't exist, allocate and insert it to the tree */
     80	node = kzalloc(sizeof(*node), GFP_KERNEL);
     81	if (!node)
     82		return NULL;
     83
     84	node->id = node_id;
     85
     86	radix_tree_insert(&nodes, node_id, node);
     87
     88	return node;
     89}
     90
     91static int server_match(const struct qrtr_server *srv,
     92			const struct qrtr_server_filter *f)
     93{
     94	unsigned int ifilter = f->ifilter;
     95
     96	if (f->service != 0 && srv->service != f->service)
     97		return 0;
     98	if (!ifilter && f->instance)
     99		ifilter = ~0;
    100
    101	return (srv->instance & ifilter) == f->instance;
    102}
    103
    104static int service_announce_new(struct sockaddr_qrtr *dest,
    105				struct qrtr_server *srv)
    106{
    107	struct qrtr_ctrl_pkt pkt;
    108	struct msghdr msg = { };
    109	struct kvec iv;
    110
    111	trace_qrtr_ns_service_announce_new(srv->service, srv->instance,
    112					   srv->node, srv->port);
    113
    114	iv.iov_base = &pkt;
    115	iv.iov_len = sizeof(pkt);
    116
    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);
    123
    124	msg.msg_name = (struct sockaddr *)dest;
    125	msg.msg_namelen = sizeof(*dest);
    126
    127	return kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
    128}
    129
    130static int service_announce_del(struct sockaddr_qrtr *dest,
    131				struct qrtr_server *srv)
    132{
    133	struct qrtr_ctrl_pkt pkt;
    134	struct msghdr msg = { };
    135	struct kvec iv;
    136	int ret;
    137
    138	trace_qrtr_ns_service_announce_del(srv->service, srv->instance,
    139					   srv->node, srv->port);
    140
    141	iv.iov_base = &pkt;
    142	iv.iov_len = sizeof(pkt);
    143
    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);
    150
    151	msg.msg_name = (struct sockaddr *)dest;
    152	msg.msg_namelen = sizeof(*dest);
    153
    154	ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
    155	if (ret < 0)
    156		pr_err("failed to announce del service\n");
    157
    158	return ret;
    159}
    160
    161static void lookup_notify(struct sockaddr_qrtr *to, struct qrtr_server *srv,
    162			  bool new)
    163{
    164	struct qrtr_ctrl_pkt pkt;
    165	struct msghdr msg = { };
    166	struct kvec iv;
    167	int ret;
    168
    169	iv.iov_base = &pkt;
    170	iv.iov_len = sizeof(pkt);
    171
    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);
    175	if (srv) {
    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);
    180	}
    181
    182	msg.msg_name = (struct sockaddr *)to;
    183	msg.msg_namelen = sizeof(*to);
    184
    185	ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
    186	if (ret < 0)
    187		pr_err("failed to send lookup notification\n");
    188}
    189
    190static int announce_servers(struct sockaddr_qrtr *sq)
    191{
    192	struct radix_tree_iter iter;
    193	struct qrtr_server *srv;
    194	struct qrtr_node *node;
    195	void __rcu **slot;
    196	int ret;
    197
    198	node = node_get(qrtr_ns.local_node);
    199	if (!node)
    200		return 0;
    201
    202	rcu_read_lock();
    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);
    206		if (!srv)
    207			continue;
    208		if (radix_tree_deref_retry(srv)) {
    209			slot = radix_tree_iter_retry(&iter);
    210			continue;
    211		}
    212		slot = radix_tree_iter_resume(slot, &iter);
    213		rcu_read_unlock();
    214
    215		ret = service_announce_new(sq, srv);
    216		if (ret < 0) {
    217			pr_err("failed to announce new service\n");
    218			return ret;
    219		}
    220
    221		rcu_read_lock();
    222	}
    223
    224	rcu_read_unlock();
    225
    226	return 0;
    227}
    228
    229static struct qrtr_server *server_add(unsigned int service,
    230				      unsigned int instance,
    231				      unsigned int node_id,
    232				      unsigned int port)
    233{
    234	struct qrtr_server *srv;
    235	struct qrtr_server *old;
    236	struct qrtr_node *node;
    237
    238	if (!service || !port)
    239		return NULL;
    240
    241	srv = kzalloc(sizeof(*srv), GFP_KERNEL);
    242	if (!srv)
    243		return NULL;
    244
    245	srv->service = service;
    246	srv->instance = instance;
    247	srv->node = node_id;
    248	srv->port = port;
    249
    250	node = node_get(node_id);
    251	if (!node)
    252		goto err;
    253
    254	/* Delete the old server on the same port */
    255	old = radix_tree_lookup(&node->servers, port);
    256	if (old) {
    257		radix_tree_delete(&node->servers, port);
    258		kfree(old);
    259	}
    260
    261	radix_tree_insert(&node->servers, port, srv);
    262
    263	trace_qrtr_ns_server_add(srv->service, srv->instance,
    264				 srv->node, srv->port);
    265
    266	return srv;
    267
    268err:
    269	kfree(srv);
    270	return NULL;
    271}
    272
    273static int server_del(struct qrtr_node *node, unsigned int port)
    274{
    275	struct qrtr_lookup *lookup;
    276	struct qrtr_server *srv;
    277	struct list_head *li;
    278
    279	srv = radix_tree_lookup(&node->servers, port);
    280	if (!srv)
    281		return -ENOENT;
    282
    283	radix_tree_delete(&node->servers, port);
    284
    285	/* Broadcast the removal of local servers */
    286	if (srv->node == qrtr_ns.local_node)
    287		service_announce_del(&qrtr_ns.bcast_sq, srv);
    288
    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)
    293			continue;
    294		if (lookup->instance && lookup->instance != srv->instance)
    295			continue;
    296
    297		lookup_notify(&lookup->sq, srv, false);
    298	}
    299
    300	kfree(srv);
    301
    302	return 0;
    303}
    304
    305static int say_hello(struct sockaddr_qrtr *dest)
    306{
    307	struct qrtr_ctrl_pkt pkt;
    308	struct msghdr msg = { };
    309	struct kvec iv;
    310	int ret;
    311
    312	iv.iov_base = &pkt;
    313	iv.iov_len = sizeof(pkt);
    314
    315	memset(&pkt, 0, sizeof(pkt));
    316	pkt.cmd = cpu_to_le32(QRTR_TYPE_HELLO);
    317
    318	msg.msg_name = (struct sockaddr *)dest;
    319	msg.msg_namelen = sizeof(*dest);
    320
    321	ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
    322	if (ret < 0)
    323		pr_err("failed to send hello msg\n");
    324
    325	return ret;
    326}
    327
    328/* Announce the list of servers registered on the local node */
    329static int ctrl_cmd_hello(struct sockaddr_qrtr *sq)
    330{
    331	int ret;
    332
    333	ret = say_hello(sq);
    334	if (ret < 0)
    335		return ret;
    336
    337	return announce_servers(sq);
    338}
    339
    340static int ctrl_cmd_bye(struct sockaddr_qrtr *from)
    341{
    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;
    349	void __rcu **slot;
    350	struct kvec iv;
    351	int ret;
    352
    353	iv.iov_base = &pkt;
    354	iv.iov_len = sizeof(pkt);
    355
    356	node = node_get(from->sq_node);
    357	if (!node)
    358		return 0;
    359
    360	rcu_read_lock();
    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);
    364		if (!srv)
    365			continue;
    366		if (radix_tree_deref_retry(srv)) {
    367			slot = radix_tree_iter_retry(&iter);
    368			continue;
    369		}
    370		slot = radix_tree_iter_resume(slot, &iter);
    371		rcu_read_unlock();
    372		server_del(node, srv->port);
    373		rcu_read_lock();
    374	}
    375	rcu_read_unlock();
    376
    377	/* Advertise the removal of this client to all local servers */
    378	local_node = node_get(qrtr_ns.local_node);
    379	if (!local_node)
    380		return 0;
    381
    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);
    385
    386	rcu_read_lock();
    387	radix_tree_for_each_slot(slot, &local_node->servers, &iter, 0) {
    388		srv = radix_tree_deref_slot(slot);
    389		if (!srv)
    390			continue;
    391		if (radix_tree_deref_retry(srv)) {
    392			slot = radix_tree_iter_retry(&iter);
    393			continue;
    394		}
    395		slot = radix_tree_iter_resume(slot, &iter);
    396		rcu_read_unlock();
    397
    398		sq.sq_family = AF_QIPCRTR;
    399		sq.sq_node = srv->node;
    400		sq.sq_port = srv->port;
    401
    402		msg.msg_name = (struct sockaddr *)&sq;
    403		msg.msg_namelen = sizeof(sq);
    404
    405		ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
    406		if (ret < 0) {
    407			pr_err("failed to send bye cmd\n");
    408			return ret;
    409		}
    410		rcu_read_lock();
    411	}
    412
    413	rcu_read_unlock();
    414
    415	return 0;
    416}
    417
    418static int ctrl_cmd_del_client(struct sockaddr_qrtr *from,
    419			       unsigned int node_id, unsigned int port)
    420{
    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;
    431	void __rcu **slot;
    432	struct kvec iv;
    433	int ret;
    434
    435	iv.iov_base = &pkt;
    436	iv.iov_len = sizeof(pkt);
    437
    438	/* Don't accept spoofed messages */
    439	if (from->sq_node != node_id)
    440		return -EINVAL;
    441
    442	/* Local DEL_CLIENT messages comes from the port being closed */
    443	if (from->sq_node == qrtr_ns.local_node && from->sq_port != port)
    444		return -EINVAL;
    445
    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)
    450			continue;
    451		if (lookup->sq.sq_port != port)
    452			continue;
    453
    454		list_del(&lookup->li);
    455		kfree(lookup);
    456	}
    457
    458	/* Remove the server belonging to this port */
    459	node = node_get(node_id);
    460	if (node)
    461		server_del(node, port);
    462
    463	/* Advertise the removal of this client to all local servers */
    464	local_node = node_get(qrtr_ns.local_node);
    465	if (!local_node)
    466		return 0;
    467
    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);
    472
    473	rcu_read_lock();
    474	radix_tree_for_each_slot(slot, &local_node->servers, &iter, 0) {
    475		srv = radix_tree_deref_slot(slot);
    476		if (!srv)
    477			continue;
    478		if (radix_tree_deref_retry(srv)) {
    479			slot = radix_tree_iter_retry(&iter);
    480			continue;
    481		}
    482		slot = radix_tree_iter_resume(slot, &iter);
    483		rcu_read_unlock();
    484
    485		sq.sq_family = AF_QIPCRTR;
    486		sq.sq_node = srv->node;
    487		sq.sq_port = srv->port;
    488
    489		msg.msg_name = (struct sockaddr *)&sq;
    490		msg.msg_namelen = sizeof(sq);
    491
    492		ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt));
    493		if (ret < 0) {
    494			pr_err("failed to send del client cmd\n");
    495			return ret;
    496		}
    497		rcu_read_lock();
    498	}
    499
    500	rcu_read_unlock();
    501
    502	return 0;
    503}
    504
    505static int ctrl_cmd_new_server(struct sockaddr_qrtr *from,
    506			       unsigned int service, unsigned int instance,
    507			       unsigned int node_id, unsigned int port)
    508{
    509	struct qrtr_lookup *lookup;
    510	struct qrtr_server *srv;
    511	struct list_head *li;
    512	int ret = 0;
    513
    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;
    518	}
    519
    520	srv = server_add(service, instance, node_id, port);
    521	if (!srv)
    522		return -EINVAL;
    523
    524	if (srv->node == qrtr_ns.local_node) {
    525		ret = service_announce_new(&qrtr_ns.bcast_sq, srv);
    526		if (ret < 0) {
    527			pr_err("failed to announce new service\n");
    528			return ret;
    529		}
    530	}
    531
    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)
    536			continue;
    537		if (lookup->instance && lookup->instance != instance)
    538			continue;
    539
    540		lookup_notify(&lookup->sq, srv, true);
    541	}
    542
    543	return ret;
    544}
    545
    546static int ctrl_cmd_del_server(struct sockaddr_qrtr *from,
    547			       unsigned int service, unsigned int instance,
    548			       unsigned int node_id, unsigned int port)
    549{
    550	struct qrtr_node *node;
    551
    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;
    556	}
    557
    558	/* Local servers may only unregister themselves */
    559	if (from->sq_node == qrtr_ns.local_node && from->sq_port != port)
    560		return -EINVAL;
    561
    562	node = node_get(node_id);
    563	if (!node)
    564		return -ENOENT;
    565
    566	return server_del(node, port);
    567}
    568
    569static int ctrl_cmd_new_lookup(struct sockaddr_qrtr *from,
    570			       unsigned int service, unsigned int instance)
    571{
    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;
    579
    580	/* Accept only local observers */
    581	if (from->sq_node != qrtr_ns.local_node)
    582		return -EINVAL;
    583
    584	lookup = kzalloc(sizeof(*lookup), GFP_KERNEL);
    585	if (!lookup)
    586		return -ENOMEM;
    587
    588	lookup->sq = *from;
    589	lookup->service = service;
    590	lookup->instance = instance;
    591	list_add_tail(&lookup->li, &qrtr_ns.lookups);
    592
    593	memset(&filter, 0, sizeof(filter));
    594	filter.service = service;
    595	filter.instance = instance;
    596
    597	rcu_read_lock();
    598	radix_tree_for_each_slot(node_slot, &nodes, &node_iter, 0) {
    599		node = radix_tree_deref_slot(node_slot);
    600		if (!node)
    601			continue;
    602		if (radix_tree_deref_retry(node)) {
    603			node_slot = radix_tree_iter_retry(&node_iter);
    604			continue;
    605		}
    606		node_slot = radix_tree_iter_resume(node_slot, &node_iter);
    607
    608		radix_tree_for_each_slot(srv_slot, &node->servers,
    609					 &srv_iter, 0) {
    610			struct qrtr_server *srv;
    611
    612			srv = radix_tree_deref_slot(srv_slot);
    613			if (!srv)
    614				continue;
    615			if (radix_tree_deref_retry(srv)) {
    616				srv_slot = radix_tree_iter_retry(&srv_iter);
    617				continue;
    618			}
    619
    620			if (!server_match(srv, &filter))
    621				continue;
    622
    623			srv_slot = radix_tree_iter_resume(srv_slot, &srv_iter);
    624
    625			rcu_read_unlock();
    626			lookup_notify(from, srv, true);
    627			rcu_read_lock();
    628		}
    629	}
    630	rcu_read_unlock();
    631
    632	/* Empty notification, to indicate end of listing */
    633	lookup_notify(from, NULL, true);
    634
    635	return 0;
    636}
    637
    638static void ctrl_cmd_del_lookup(struct sockaddr_qrtr *from,
    639				unsigned int service, unsigned int instance)
    640{
    641	struct qrtr_lookup *lookup;
    642	struct list_head *tmp;
    643	struct list_head *li;
    644
    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)
    648			continue;
    649		if (lookup->sq.sq_port != from->sq_port)
    650			continue;
    651		if (lookup->service != service)
    652			continue;
    653		if (lookup->instance && lookup->instance != instance)
    654			continue;
    655
    656		list_del(&lookup->li);
    657		kfree(lookup);
    658	}
    659}
    660
    661static void qrtr_ns_worker(struct work_struct *work)
    662{
    663	const struct qrtr_ctrl_pkt *pkt;
    664	size_t recv_buf_size = 4096;
    665	struct sockaddr_qrtr sq;
    666	struct msghdr msg = { };
    667	unsigned int cmd;
    668	ssize_t msglen;
    669	void *recv_buf;
    670	struct kvec iv;
    671	int ret;
    672
    673	msg.msg_name = (struct sockaddr *)&sq;
    674	msg.msg_namelen = sizeof(sq);
    675
    676	recv_buf = kzalloc(recv_buf_size, GFP_KERNEL);
    677	if (!recv_buf)
    678		return;
    679
    680	for (;;) {
    681		iv.iov_base = recv_buf;
    682		iv.iov_len = recv_buf_size;
    683
    684		msglen = kernel_recvmsg(qrtr_ns.sock, &msg, &iv, 1,
    685					iv.iov_len, MSG_DONTWAIT);
    686
    687		if (msglen == -EAGAIN)
    688			break;
    689
    690		if (msglen < 0) {
    691			pr_err("error receiving packet: %zd\n", msglen);
    692			break;
    693		}
    694
    695		pkt = recv_buf;
    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);
    701
    702		ret = 0;
    703		switch (cmd) {
    704		case QRTR_TYPE_HELLO:
    705			ret = ctrl_cmd_hello(&sq);
    706			break;
    707		case QRTR_TYPE_BYE:
    708			ret = ctrl_cmd_bye(&sq);
    709			break;
    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));
    714			break;
    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));
    721			break;
    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));
    728			break;
    729		case QRTR_TYPE_EXIT:
    730		case QRTR_TYPE_PING:
    731		case QRTR_TYPE_RESUME_TX:
    732			break;
    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));
    737			break;
    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));
    742			break;
    743		}
    744
    745		if (ret < 0)
    746			pr_err("failed while handling packet from %d:%d",
    747			       sq.sq_node, sq.sq_port);
    748	}
    749
    750	kfree(recv_buf);
    751}
    752
    753static void qrtr_ns_data_ready(struct sock *sk)
    754{
    755	queue_work(qrtr_ns.workqueue, &qrtr_ns.work);
    756}
    757
    758int qrtr_ns_init(void)
    759{
    760	struct sockaddr_qrtr sq;
    761	int ret;
    762
    763	INIT_LIST_HEAD(&qrtr_ns.lookups);
    764	INIT_WORK(&qrtr_ns.work, qrtr_ns_worker);
    765
    766	ret = sock_create_kern(&init_net, AF_QIPCRTR, SOCK_DGRAM,
    767			       PF_QIPCRTR, &qrtr_ns.sock);
    768	if (ret < 0)
    769		return ret;
    770
    771	ret = kernel_getsockname(qrtr_ns.sock, (struct sockaddr *)&sq);
    772	if (ret < 0) {
    773		pr_err("failed to get socket name\n");
    774		goto err_sock;
    775	}
    776
    777	qrtr_ns.workqueue = alloc_workqueue("qrtr_ns_handler", WQ_UNBOUND, 1);
    778	if (!qrtr_ns.workqueue) {
    779		ret = -ENOMEM;
    780		goto err_sock;
    781	}
    782
    783	qrtr_ns.sock->sk->sk_data_ready = qrtr_ns_data_ready;
    784
    785	sq.sq_port = QRTR_PORT_CTRL;
    786	qrtr_ns.local_node = sq.sq_node;
    787
    788	ret = kernel_bind(qrtr_ns.sock, (struct sockaddr *)&sq, sizeof(sq));
    789	if (ret < 0) {
    790		pr_err("failed to bind to socket\n");
    791		goto err_wq;
    792	}
    793
    794	qrtr_ns.bcast_sq.sq_family = AF_QIPCRTR;
    795	qrtr_ns.bcast_sq.sq_node = QRTR_NODE_BCAST;
    796	qrtr_ns.bcast_sq.sq_port = QRTR_PORT_CTRL;
    797
    798	ret = say_hello(&qrtr_ns.bcast_sq);
    799	if (ret < 0)
    800		goto err_wq;
    801
    802	return 0;
    803
    804err_wq:
    805	destroy_workqueue(qrtr_ns.workqueue);
    806err_sock:
    807	sock_release(qrtr_ns.sock);
    808	return ret;
    809}
    810EXPORT_SYMBOL_GPL(qrtr_ns_init);
    811
    812void qrtr_ns_remove(void)
    813{
    814	cancel_work_sync(&qrtr_ns.work);
    815	destroy_workqueue(qrtr_ns.workqueue);
    816	sock_release(qrtr_ns.sock);
    817}
    818EXPORT_SYMBOL_GPL(qrtr_ns_remove);
    819
    820MODULE_AUTHOR("Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>");
    821MODULE_DESCRIPTION("Qualcomm IPC Router Nameservice");
    822MODULE_LICENSE("Dual BSD/GPL");