ipc_router_socket.c 17 KB

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