PageRenderTime 53ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/net/ipc_router/ipc_router_socket.c

https://gitlab.com/webhaikal/SenseiOneplus3
C | 693 lines | 572 code | 94 blank | 27 comment | 103 complexity | fa59d08b7522d3cb2671ed395f0adbb2 MD5 | raw file
  1. /* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. */
  12. #include <linux/module.h>
  13. #include <linux/types.h>
  14. #include <linux/net.h>
  15. #include <linux/socket.h>
  16. #include <linux/errno.h>
  17. #include <linux/mm.h>
  18. #include <linux/poll.h>
  19. #include <linux/fcntl.h>
  20. #include <linux/gfp.h>
  21. #include <linux/msm_ipc.h>
  22. #include <linux/sched.h>
  23. #include <linux/thread_info.h>
  24. #include <linux/qmi_encdec.h>
  25. #include <linux/slab.h>
  26. #include <linux/kmemleak.h>
  27. #include <linux/ipc_logging.h>
  28. #include <linux/string.h>
  29. #include <linux/atomic.h>
  30. #include <linux/ipc_router.h>
  31. #include <net/sock.h>
  32. #include "ipc_router_private.h"
  33. #include "ipc_router_security.h"
  34. #define msm_ipc_sk(sk) ((struct msm_ipc_sock *)(sk))
  35. #define msm_ipc_sk_port(sk) ((struct msm_ipc_port *)(msm_ipc_sk(sk)->port))
  36. #ifndef SIZE_MAX
  37. #define SIZE_MAX ((size_t)-1)
  38. #endif
  39. static int sockets_enabled;
  40. static struct proto msm_ipc_proto;
  41. static const struct proto_ops msm_ipc_proto_ops;
  42. static RAW_NOTIFIER_HEAD(ipcrtr_af_init_chain);
  43. static DEFINE_MUTEX(ipcrtr_af_init_lock);
  44. static struct sk_buff_head *msm_ipc_router_build_msg(unsigned int num_sect,
  45. struct iovec const *msg_sect,
  46. size_t total_len)
  47. {
  48. struct sk_buff_head *msg_head;
  49. struct sk_buff *msg;
  50. int i, copied, first = 1;
  51. int data_size = 0, request_size, offset;
  52. void *data;
  53. int last = 0;
  54. int align_size;
  55. for (i = 0; i < num_sect; i++)
  56. data_size += msg_sect[i].iov_len;
  57. if (!data_size)
  58. return NULL;
  59. align_size = ALIGN_SIZE(data_size);
  60. msg_head = kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);
  61. if (!msg_head) {
  62. IPC_RTR_ERR("%s: cannot allocate skb_head\n", __func__);
  63. return NULL;
  64. }
  65. skb_queue_head_init(msg_head);
  66. for (copied = 1, i = 0; copied && (i < num_sect); i++) {
  67. data_size = msg_sect[i].iov_len;
  68. offset = 0;
  69. if (i == (num_sect - 1))
  70. last = 1;
  71. while (offset != msg_sect[i].iov_len) {
  72. request_size = data_size;
  73. if (first)
  74. request_size += IPC_ROUTER_HDR_SIZE;
  75. if (last)
  76. request_size += align_size;
  77. msg = alloc_skb(request_size, GFP_KERNEL);
  78. if (!msg) {
  79. if (request_size <= (PAGE_SIZE/2)) {
  80. IPC_RTR_ERR(
  81. "%s: cannot allocated skb\n",
  82. __func__);
  83. goto msg_build_failure;
  84. }
  85. data_size = data_size / 2;
  86. last = 0;
  87. continue;
  88. }
  89. if (first) {
  90. skb_reserve(msg, IPC_ROUTER_HDR_SIZE);
  91. first = 0;
  92. }
  93. data = skb_put(msg, data_size);
  94. copied = !copy_from_user(msg->data,
  95. msg_sect[i].iov_base + offset,
  96. data_size);
  97. if (!copied) {
  98. IPC_RTR_ERR("%s: copy_from_user failed\n",
  99. __func__);
  100. kfree_skb(msg);
  101. goto msg_build_failure;
  102. }
  103. skb_queue_tail(msg_head, msg);
  104. offset += data_size;
  105. data_size = msg_sect[i].iov_len - offset;
  106. if (i == (num_sect - 1))
  107. last = 1;
  108. }
  109. }
  110. return msg_head;
  111. msg_build_failure:
  112. while (!skb_queue_empty(msg_head)) {
  113. msg = skb_dequeue(msg_head);
  114. kfree_skb(msg);
  115. }
  116. kfree(msg_head);
  117. return NULL;
  118. }
  119. static int msm_ipc_router_extract_msg(struct msghdr *m,
  120. struct rr_packet *pkt)
  121. {
  122. struct sockaddr_msm_ipc *addr;
  123. struct rr_header_v1 *hdr;
  124. struct sk_buff *temp;
  125. union rr_control_msg *ctl_msg;
  126. int offset = 0, data_len = 0, copy_len;
  127. if (!m || !pkt) {
  128. IPC_RTR_ERR("%s: Invalid pointers passed\n", __func__);
  129. return -EINVAL;
  130. }
  131. addr = (struct sockaddr_msm_ipc *)m->msg_name;
  132. hdr = &(pkt->hdr);
  133. if (addr && (hdr->type == IPC_ROUTER_CTRL_CMD_RESUME_TX)) {
  134. temp = skb_peek(pkt->pkt_fragment_q);
  135. ctl_msg = (union rr_control_msg *)(temp->data);
  136. addr->family = AF_MSM_IPC;
  137. addr->address.addrtype = MSM_IPC_ADDR_ID;
  138. addr->address.addr.port_addr.node_id = ctl_msg->cli.node_id;
  139. addr->address.addr.port_addr.port_id = ctl_msg->cli.port_id;
  140. m->msg_namelen = sizeof(struct sockaddr_msm_ipc);
  141. return offset;
  142. }
  143. if (addr && (hdr->type == IPC_ROUTER_CTRL_CMD_DATA)) {
  144. addr->family = AF_MSM_IPC;
  145. addr->address.addrtype = MSM_IPC_ADDR_ID;
  146. addr->address.addr.port_addr.node_id = hdr->src_node_id;
  147. addr->address.addr.port_addr.port_id = hdr->src_port_id;
  148. m->msg_namelen = sizeof(struct sockaddr_msm_ipc);
  149. }
  150. data_len = hdr->size;
  151. skb_queue_walk(pkt->pkt_fragment_q, temp) {
  152. copy_len = data_len < temp->len ? data_len : temp->len;
  153. if (copy_to_user(m->msg_iov->iov_base + offset, temp->data,
  154. copy_len)) {
  155. IPC_RTR_ERR("%s: Copy to user failed\n", __func__);
  156. return -EFAULT;
  157. }
  158. offset += copy_len;
  159. data_len -= copy_len;
  160. }
  161. return offset;
  162. }
  163. static int msm_ipc_router_create(struct net *net,
  164. struct socket *sock,
  165. int protocol,
  166. int kern)
  167. {
  168. struct sock *sk;
  169. struct msm_ipc_port *port_ptr;
  170. if (unlikely(protocol != 0)) {
  171. IPC_RTR_ERR("%s: Protocol not supported\n", __func__);
  172. return -EPROTONOSUPPORT;
  173. }
  174. switch (sock->type) {
  175. case SOCK_DGRAM:
  176. break;
  177. default:
  178. IPC_RTR_ERR("%s: Protocol type not supported\n", __func__);
  179. return -EPROTOTYPE;
  180. }
  181. sk = sk_alloc(net, AF_MSM_IPC, GFP_KERNEL, &msm_ipc_proto);
  182. if (!sk) {
  183. IPC_RTR_ERR("%s: sk_alloc failed\n", __func__);
  184. return -ENOMEM;
  185. }
  186. sock->ops = &msm_ipc_proto_ops;
  187. sock_init_data(sock, sk);
  188. sk->sk_data_ready = NULL;
  189. sk->sk_write_space = NULL;
  190. sk->sk_rcvtimeo = DEFAULT_RCV_TIMEO;
  191. sk->sk_sndtimeo = DEFAULT_SND_TIMEO;
  192. port_ptr = msm_ipc_router_create_raw_port(sk, NULL, NULL);
  193. if (!port_ptr) {
  194. IPC_RTR_ERR("%s: port_ptr alloc failed\n", __func__);
  195. sock_put(sk);
  196. sock->sk = NULL;
  197. return -ENOMEM;
  198. }
  199. port_ptr->check_send_permissions = msm_ipc_check_send_permissions;
  200. msm_ipc_sk(sk)->port = port_ptr;
  201. msm_ipc_sk(sk)->default_node_vote_info = NULL;
  202. return 0;
  203. }
  204. int msm_ipc_router_bind(struct socket *sock, struct sockaddr *uaddr,
  205. int uaddr_len)
  206. {
  207. struct sockaddr_msm_ipc *addr = (struct sockaddr_msm_ipc *)uaddr;
  208. struct sock *sk = sock->sk;
  209. struct msm_ipc_port *port_ptr;
  210. int ret;
  211. if (!sk)
  212. return -EINVAL;
  213. if (!check_permissions()) {
  214. IPC_RTR_ERR("%s: %s Do not have permissions\n",
  215. __func__, current->comm);
  216. return -EPERM;
  217. }
  218. if (!uaddr_len) {
  219. IPC_RTR_ERR("%s: Invalid address length\n", __func__);
  220. return -EINVAL;
  221. }
  222. if (addr->family != AF_MSM_IPC) {
  223. IPC_RTR_ERR("%s: Address family is incorrect\n", __func__);
  224. return -EAFNOSUPPORT;
  225. }
  226. if (addr->address.addrtype != MSM_IPC_ADDR_NAME) {
  227. IPC_RTR_ERR("%s: Address type is incorrect\n", __func__);
  228. return -EINVAL;
  229. }
  230. port_ptr = msm_ipc_sk_port(sk);
  231. if (!port_ptr)
  232. return -ENODEV;
  233. if (!msm_ipc_sk(sk)->default_node_vote_info)
  234. msm_ipc_sk(sk)->default_node_vote_info =
  235. msm_ipc_load_default_node();
  236. lock_sock(sk);
  237. ret = msm_ipc_router_register_server(port_ptr, &addr->address);
  238. release_sock(sk);
  239. return ret;
  240. }
  241. static int ipc_router_connect(struct socket *sock, struct sockaddr *uaddr,
  242. int uaddr_len, int flags)
  243. {
  244. struct sockaddr_msm_ipc *addr = (struct sockaddr_msm_ipc *)uaddr;
  245. struct sock *sk = sock->sk;
  246. struct msm_ipc_port *port_ptr;
  247. int ret;
  248. if (!sk)
  249. return -EINVAL;
  250. if (uaddr_len <= 0) {
  251. IPC_RTR_ERR("%s: Invalid address length\n", __func__);
  252. return -EINVAL;
  253. }
  254. if (!addr) {
  255. IPC_RTR_ERR("%s: Invalid address\n", __func__);
  256. return -EINVAL;
  257. }
  258. if (addr->family != AF_MSM_IPC) {
  259. IPC_RTR_ERR("%s: Address family is incorrect\n", __func__);
  260. return -EAFNOSUPPORT;
  261. }
  262. port_ptr = msm_ipc_sk_port(sk);
  263. if (!port_ptr)
  264. return -ENODEV;
  265. lock_sock(sk);
  266. ret = ipc_router_set_conn(port_ptr, &addr->address);
  267. release_sock(sk);
  268. return ret;
  269. }
  270. static int msm_ipc_router_sendmsg(struct kiocb *iocb, struct socket *sock,
  271. struct msghdr *m, size_t total_len)
  272. {
  273. struct sock *sk = sock->sk;
  274. struct msm_ipc_port *port_ptr = msm_ipc_sk_port(sk);
  275. struct sockaddr_msm_ipc *dest = (struct sockaddr_msm_ipc *)m->msg_name;
  276. struct sk_buff_head *msg;
  277. int ret;
  278. struct msm_ipc_addr dest_addr = {0};
  279. long timeout;
  280. if (dest) {
  281. if (m->msg_namelen < sizeof(*dest) ||
  282. dest->family != AF_MSM_IPC)
  283. return -EINVAL;
  284. memcpy(&dest_addr, &dest->address, sizeof(dest_addr));
  285. } else {
  286. if (port_ptr->conn_status == NOT_CONNECTED) {
  287. return -EDESTADDRREQ;
  288. } else if (port_ptr->conn_status < CONNECTION_RESET) {
  289. return -ENETRESET;
  290. } else {
  291. memcpy(&dest_addr.addr.port_addr, &port_ptr->dest_addr,
  292. sizeof(struct msm_ipc_port_addr));
  293. dest_addr.addrtype = MSM_IPC_ADDR_ID;
  294. }
  295. }
  296. if (total_len > MAX_IPC_PKT_SIZE)
  297. return -EINVAL;
  298. lock_sock(sk);
  299. timeout = sock_sndtimeo(sk, m->msg_flags & MSG_DONTWAIT);
  300. msg = msm_ipc_router_build_msg(m->msg_iovlen, m->msg_iov, total_len);
  301. if (!msg) {
  302. IPC_RTR_ERR("%s: Msg build failure\n", __func__);
  303. ret = -ENOMEM;
  304. goto out_sendmsg;
  305. }
  306. kmemleak_not_leak(msg);
  307. if (port_ptr->type == CLIENT_PORT)
  308. wait_for_irsc_completion();
  309. ret = msm_ipc_router_send_to(port_ptr, msg, &dest_addr, timeout);
  310. if (ret != total_len) {
  311. if (ret < 0) {
  312. if (ret != -EAGAIN)
  313. IPC_RTR_ERR("%s: Send_to failure %d\n",
  314. __func__, ret);
  315. msm_ipc_router_free_skb(msg);
  316. } else if (ret >= 0) {
  317. ret = -EFAULT;
  318. }
  319. }
  320. out_sendmsg:
  321. release_sock(sk);
  322. return ret;
  323. }
  324. static int msm_ipc_router_recvmsg(struct kiocb *iocb, struct socket *sock,
  325. struct msghdr *m, size_t buf_len, int flags)
  326. {
  327. struct sock *sk = sock->sk;
  328. struct msm_ipc_port *port_ptr = msm_ipc_sk_port(sk);
  329. struct rr_packet *pkt;
  330. long timeout;
  331. int ret;
  332. if (m->msg_iovlen != 1)
  333. return -EOPNOTSUPP;
  334. lock_sock(sk);
  335. if (!buf_len) {
  336. if (flags & MSG_PEEK)
  337. ret = msm_ipc_router_get_curr_pkt_size(port_ptr);
  338. else
  339. ret = -EINVAL;
  340. release_sock(sk);
  341. return ret;
  342. }
  343. timeout = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
  344. ret = msm_ipc_router_rx_data_wait(port_ptr, timeout);
  345. if (ret) {
  346. release_sock(sk);
  347. if (ret == -ENOMSG)
  348. m->msg_namelen = 0;
  349. return ret;
  350. }
  351. ret = msm_ipc_router_read(port_ptr, &pkt, buf_len);
  352. if (ret <= 0 || !pkt) {
  353. release_sock(sk);
  354. return ret;
  355. }
  356. ret = msm_ipc_router_extract_msg(m, pkt);
  357. release_pkt(pkt);
  358. release_sock(sk);
  359. return ret;
  360. }
  361. static int msm_ipc_router_ioctl(struct socket *sock,
  362. unsigned int cmd, unsigned long arg)
  363. {
  364. struct sock *sk = sock->sk;
  365. struct msm_ipc_port *port_ptr;
  366. struct server_lookup_args server_arg;
  367. struct msm_ipc_server_info *srv_info = NULL;
  368. unsigned int n;
  369. size_t srv_info_sz = 0;
  370. int ret;
  371. if (!sk)
  372. return -EINVAL;
  373. lock_sock(sk);
  374. port_ptr = msm_ipc_sk_port(sock->sk);
  375. if (!port_ptr) {
  376. release_sock(sk);
  377. return -EINVAL;
  378. }
  379. switch (cmd) {
  380. case IPC_ROUTER_IOCTL_GET_VERSION:
  381. n = IPC_ROUTER_V1;
  382. ret = put_user(n, (unsigned int *)arg);
  383. break;
  384. case IPC_ROUTER_IOCTL_GET_MTU:
  385. n = (MAX_IPC_PKT_SIZE - IPC_ROUTER_HDR_SIZE);
  386. ret = put_user(n, (unsigned int *)arg);
  387. break;
  388. case IPC_ROUTER_IOCTL_GET_CURR_PKT_SIZE:
  389. ret = msm_ipc_router_get_curr_pkt_size(port_ptr);
  390. break;
  391. case IPC_ROUTER_IOCTL_LOOKUP_SERVER:
  392. if (!msm_ipc_sk(sk)->default_node_vote_info)
  393. msm_ipc_sk(sk)->default_node_vote_info =
  394. msm_ipc_load_default_node();
  395. ret = copy_from_user(&server_arg, (void *)arg,
  396. sizeof(server_arg));
  397. if (ret) {
  398. ret = -EFAULT;
  399. break;
  400. }
  401. if (server_arg.num_entries_in_array < 0) {
  402. ret = -EINVAL;
  403. break;
  404. }
  405. if (server_arg.num_entries_in_array) {
  406. if (server_arg.num_entries_in_array >
  407. (SIZE_MAX / sizeof(*srv_info))) {
  408. IPC_RTR_ERR("%s: Integer Overflow %zu * %d\n",
  409. __func__, sizeof(*srv_info),
  410. server_arg.num_entries_in_array);
  411. ret = -EINVAL;
  412. break;
  413. }
  414. srv_info_sz = server_arg.num_entries_in_array *
  415. sizeof(*srv_info);
  416. srv_info = kmalloc(srv_info_sz, GFP_KERNEL);
  417. if (!srv_info) {
  418. ret = -ENOMEM;
  419. break;
  420. }
  421. }
  422. ret = msm_ipc_router_lookup_server_name(&server_arg.port_name,
  423. srv_info, server_arg.num_entries_in_array,
  424. server_arg.lookup_mask);
  425. if (ret < 0) {
  426. IPC_RTR_ERR("%s: Server not found\n", __func__);
  427. ret = -ENODEV;
  428. kfree(srv_info);
  429. break;
  430. }
  431. server_arg.num_entries_found = ret;
  432. ret = copy_to_user((void *)arg, &server_arg,
  433. sizeof(server_arg));
  434. n = min(server_arg.num_entries_found,
  435. server_arg.num_entries_in_array);
  436. if (ret == 0 && n) {
  437. ret = copy_to_user((void *)(arg + sizeof(server_arg)),
  438. srv_info, n * sizeof(*srv_info));
  439. }
  440. if (ret)
  441. ret = -EFAULT;
  442. kfree(srv_info);
  443. break;
  444. case IPC_ROUTER_IOCTL_BIND_CONTROL_PORT:
  445. ret = msm_ipc_router_bind_control_port(port_ptr);
  446. break;
  447. case IPC_ROUTER_IOCTL_CONFIG_SEC_RULES:
  448. ret = msm_ipc_config_sec_rules((void *)arg);
  449. if (ret != -EPERM)
  450. port_ptr->type = IRSC_PORT;
  451. break;
  452. default:
  453. ret = -EINVAL;
  454. }
  455. release_sock(sk);
  456. return ret;
  457. }
  458. static unsigned int msm_ipc_router_poll(struct file *file,
  459. struct socket *sock, poll_table *wait)
  460. {
  461. struct sock *sk = sock->sk;
  462. struct msm_ipc_port *port_ptr;
  463. uint32_t mask = 0;
  464. if (!sk)
  465. return -EINVAL;
  466. port_ptr = msm_ipc_sk_port(sk);
  467. if (!port_ptr)
  468. return -EINVAL;
  469. poll_wait(file, &port_ptr->port_rx_wait_q, wait);
  470. if (!list_empty(&port_ptr->port_rx_q))
  471. mask |= (POLLRDNORM | POLLIN);
  472. if (port_ptr->conn_status == CONNECTION_RESET)
  473. mask |= (POLLHUP | POLLERR);
  474. return mask;
  475. }
  476. static int msm_ipc_router_close(struct socket *sock)
  477. {
  478. struct sock *sk = sock->sk;
  479. struct msm_ipc_port *port_ptr = msm_ipc_sk_port(sk);
  480. int ret;
  481. lock_sock(sk);
  482. ret = msm_ipc_router_close_port(port_ptr);
  483. msm_ipc_unload_default_node(msm_ipc_sk(sk)->default_node_vote_info);
  484. release_sock(sk);
  485. sock_put(sk);
  486. sock->sk = NULL;
  487. return ret;
  488. }
  489. /**
  490. * register_ipcrtr_af_init_notifier() - Register for ipc router socket
  491. * address family initialization callback
  492. * @nb: Notifier block which will be notified when address family is
  493. * initialized.
  494. *
  495. * Return: 0 on success, standard error code otherwise.
  496. */
  497. int register_ipcrtr_af_init_notifier(struct notifier_block *nb)
  498. {
  499. int ret;
  500. if (!nb)
  501. return -EINVAL;
  502. mutex_lock(&ipcrtr_af_init_lock);
  503. if (sockets_enabled)
  504. nb->notifier_call(nb, IPCRTR_AF_INIT, NULL);
  505. ret = raw_notifier_chain_register(&ipcrtr_af_init_chain, nb);
  506. mutex_unlock(&ipcrtr_af_init_lock);
  507. return ret;
  508. }
  509. EXPORT_SYMBOL(register_ipcrtr_af_init_notifier);
  510. /**
  511. * unregister_ipcrtr_af_init_notifier() - Unregister for ipc router socket
  512. * address family initialization callback
  513. * @nb: Notifier block which will be notified once address family is
  514. * initialized.
  515. *
  516. * Return: 0 on success, standard error code otherwise.
  517. */
  518. int unregister_ipcrtr_af_init_notifier(struct notifier_block *nb)
  519. {
  520. int ret;
  521. if (!nb)
  522. return -EINVAL;
  523. ret = raw_notifier_chain_unregister(&ipcrtr_af_init_chain, nb);
  524. return ret;
  525. }
  526. EXPORT_SYMBOL(unregister_ipcrtr_af_init_notifier);
  527. static const struct net_proto_family msm_ipc_family_ops = {
  528. .owner = THIS_MODULE,
  529. .family = AF_MSM_IPC,
  530. .create = msm_ipc_router_create
  531. };
  532. static const struct proto_ops msm_ipc_proto_ops = {
  533. .family = AF_MSM_IPC,
  534. .owner = THIS_MODULE,
  535. .release = msm_ipc_router_close,
  536. .bind = msm_ipc_router_bind,
  537. .connect = ipc_router_connect,
  538. .socketpair = sock_no_socketpair,
  539. .accept = sock_no_accept,
  540. .getname = sock_no_getname,
  541. .poll = msm_ipc_router_poll,
  542. .ioctl = msm_ipc_router_ioctl,
  543. #ifdef CONFIG_COMPAT
  544. .compat_ioctl = msm_ipc_router_ioctl,
  545. #endif
  546. .listen = sock_no_listen,
  547. .shutdown = sock_no_shutdown,
  548. .setsockopt = sock_no_setsockopt,
  549. .getsockopt = sock_no_getsockopt,
  550. #ifdef CONFIG_COMPAT
  551. .compat_setsockopt = sock_no_setsockopt,
  552. .compat_getsockopt = sock_no_getsockopt,
  553. #endif
  554. .sendmsg = msm_ipc_router_sendmsg,
  555. .recvmsg = msm_ipc_router_recvmsg,
  556. .mmap = sock_no_mmap,
  557. .sendpage = sock_no_sendpage,
  558. };
  559. static struct proto msm_ipc_proto = {
  560. .name = "MSM_IPC",
  561. .owner = THIS_MODULE,
  562. .obj_size = sizeof(struct msm_ipc_sock),
  563. };
  564. int msm_ipc_router_init_sockets(void)
  565. {
  566. int ret;
  567. ret = proto_register(&msm_ipc_proto, 1);
  568. if (ret) {
  569. IPC_RTR_ERR("%s: Failed to register MSM_IPC protocol type\n",
  570. __func__);
  571. goto out_init_sockets;
  572. }
  573. ret = sock_register(&msm_ipc_family_ops);
  574. if (ret) {
  575. IPC_RTR_ERR("%s: Failed to register MSM_IPC socket type\n",
  576. __func__);
  577. proto_unregister(&msm_ipc_proto);
  578. goto out_init_sockets;
  579. }
  580. mutex_lock(&ipcrtr_af_init_lock);
  581. sockets_enabled = 1;
  582. raw_notifier_call_chain(&ipcrtr_af_init_chain,
  583. IPCRTR_AF_INIT, NULL);
  584. mutex_unlock(&ipcrtr_af_init_lock);
  585. out_init_sockets:
  586. return ret;
  587. }
  588. void msm_ipc_router_exit_sockets(void)
  589. {
  590. if (!sockets_enabled)
  591. return;
  592. sock_unregister(msm_ipc_family_ops.family);
  593. proto_unregister(&msm_ipc_proto);
  594. mutex_lock(&ipcrtr_af_init_lock);
  595. sockets_enabled = 0;
  596. raw_notifier_call_chain(&ipcrtr_af_init_chain,
  597. IPCRTR_AF_DEINIT, NULL);
  598. mutex_unlock(&ipcrtr_af_init_lock);
  599. }