usnic_transport.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * Copyright (c) 2013, Cisco Systems, Inc. All rights reserved.
  3. *
  4. * This software is available to you under a choice of one of two
  5. * licenses. You may choose to be licensed under the terms of the GNU
  6. * General Public License (GPL) Version 2, available from the file
  7. * COPYING in the main directory of this source tree, or the
  8. * BSD license below:
  9. *
  10. * Redistribution and use in source and binary forms, with or
  11. * without modification, are permitted provided that the following
  12. * conditions are met:
  13. *
  14. * - Redistributions of source code must retain the above
  15. * copyright notice, this list of conditions and the following
  16. * disclaimer.
  17. *
  18. * - Redistributions in binary form must reproduce the above
  19. * copyright notice, this list of conditions and the following
  20. * disclaimer in the documentation and/or other materials
  21. * provided with the distribution.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  27. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  28. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  29. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  30. * SOFTWARE.
  31. *
  32. */
  33. #include <linux/bitmap.h>
  34. #include <linux/file.h>
  35. #include <linux/module.h>
  36. #include <linux/slab.h>
  37. #include <net/inet_sock.h>
  38. #include "usnic_transport.h"
  39. #include "usnic_log.h"
  40. /* ROCE */
  41. static unsigned long *roce_bitmap;
  42. static u16 roce_next_port = 1;
  43. #define ROCE_BITMAP_SZ ((1 << (8 /*CHAR_BIT*/ * sizeof(u16)))/8 /*CHAR BIT*/)
  44. static DEFINE_SPINLOCK(roce_bitmap_lock);
  45. const char *usnic_transport_to_str(enum usnic_transport_type type)
  46. {
  47. switch (type) {
  48. case USNIC_TRANSPORT_UNKNOWN:
  49. return "Unknown";
  50. case USNIC_TRANSPORT_ROCE_CUSTOM:
  51. return "roce custom";
  52. case USNIC_TRANSPORT_IPV4_UDP:
  53. return "IPv4 UDP";
  54. case USNIC_TRANSPORT_MAX:
  55. return "Max?";
  56. default:
  57. return "Not known";
  58. }
  59. }
  60. int usnic_transport_sock_to_str(char *buf, int buf_sz,
  61. struct socket *sock)
  62. {
  63. int err;
  64. uint32_t addr;
  65. uint16_t port;
  66. int proto;
  67. memset(buf, 0, buf_sz);
  68. err = usnic_transport_sock_get_addr(sock, &proto, &addr, &port);
  69. if (err)
  70. return 0;
  71. return scnprintf(buf, buf_sz, "Proto:%u Addr:%pI4h Port:%hu",
  72. proto, &addr, port);
  73. }
  74. /*
  75. * reserve a port number. if "0" specified, we will try to pick one
  76. * starting at roce_next_port. roce_next_port will take on the values
  77. * 1..4096
  78. */
  79. u16 usnic_transport_rsrv_port(enum usnic_transport_type type, u16 port_num)
  80. {
  81. if (type == USNIC_TRANSPORT_ROCE_CUSTOM) {
  82. spin_lock(&roce_bitmap_lock);
  83. if (!port_num) {
  84. port_num = bitmap_find_next_zero_area(roce_bitmap,
  85. ROCE_BITMAP_SZ,
  86. roce_next_port /* start */,
  87. 1 /* nr */,
  88. 0 /* align */);
  89. roce_next_port = (port_num & 4095) + 1;
  90. } else if (test_bit(port_num, roce_bitmap)) {
  91. usnic_err("Failed to allocate port for %s\n",
  92. usnic_transport_to_str(type));
  93. spin_unlock(&roce_bitmap_lock);
  94. goto out_fail;
  95. }
  96. bitmap_set(roce_bitmap, port_num, 1);
  97. spin_unlock(&roce_bitmap_lock);
  98. } else {
  99. usnic_err("Failed to allocate port - transport %s unsupported\n",
  100. usnic_transport_to_str(type));
  101. goto out_fail;
  102. }
  103. usnic_dbg("Allocating port %hu for %s\n", port_num,
  104. usnic_transport_to_str(type));
  105. return port_num;
  106. out_fail:
  107. return 0;
  108. }
  109. void usnic_transport_unrsrv_port(enum usnic_transport_type type, u16 port_num)
  110. {
  111. if (type == USNIC_TRANSPORT_ROCE_CUSTOM) {
  112. spin_lock(&roce_bitmap_lock);
  113. if (!port_num) {
  114. usnic_err("Unreserved unvalid port num 0 for %s\n",
  115. usnic_transport_to_str(type));
  116. goto out_roce_custom;
  117. }
  118. if (!test_bit(port_num, roce_bitmap)) {
  119. usnic_err("Unreserving invalid %hu for %s\n",
  120. port_num,
  121. usnic_transport_to_str(type));
  122. goto out_roce_custom;
  123. }
  124. bitmap_clear(roce_bitmap, port_num, 1);
  125. usnic_dbg("Freeing port %hu for %s\n", port_num,
  126. usnic_transport_to_str(type));
  127. out_roce_custom:
  128. spin_unlock(&roce_bitmap_lock);
  129. } else {
  130. usnic_err("Freeing invalid port %hu for %d\n", port_num, type);
  131. }
  132. }
  133. struct socket *usnic_transport_get_socket(int sock_fd)
  134. {
  135. struct socket *sock;
  136. int err;
  137. char buf[25];
  138. /* sockfd_lookup will internally do a fget */
  139. sock = sockfd_lookup(sock_fd, &err);
  140. if (!sock) {
  141. usnic_err("Unable to lookup socket for fd %d with err %d\n",
  142. sock_fd, err);
  143. return ERR_PTR(-ENOENT);
  144. }
  145. usnic_transport_sock_to_str(buf, sizeof(buf), sock);
  146. usnic_dbg("Get sock %s\n", buf);
  147. return sock;
  148. }
  149. void usnic_transport_put_socket(struct socket *sock)
  150. {
  151. char buf[100];
  152. usnic_transport_sock_to_str(buf, sizeof(buf), sock);
  153. usnic_dbg("Put sock %s\n", buf);
  154. sockfd_put(sock);
  155. }
  156. int usnic_transport_sock_get_addr(struct socket *sock, int *proto,
  157. uint32_t *addr, uint16_t *port)
  158. {
  159. int err;
  160. struct sockaddr_in sock_addr;
  161. err = sock->ops->getname(sock,
  162. (struct sockaddr *)&sock_addr,
  163. 0);
  164. if (err < 0)
  165. return err;
  166. if (sock_addr.sin_family != AF_INET)
  167. return -EINVAL;
  168. if (proto)
  169. *proto = sock->sk->sk_protocol;
  170. if (port)
  171. *port = ntohs(((struct sockaddr_in *)&sock_addr)->sin_port);
  172. if (addr)
  173. *addr = ntohl(((struct sockaddr_in *)
  174. &sock_addr)->sin_addr.s_addr);
  175. return 0;
  176. }
  177. int usnic_transport_init(void)
  178. {
  179. roce_bitmap = kzalloc(ROCE_BITMAP_SZ, GFP_KERNEL);
  180. if (!roce_bitmap)
  181. return -ENOMEM;
  182. /* Do not ever allocate bit 0, hence set it here */
  183. bitmap_set(roce_bitmap, 0, 1);
  184. return 0;
  185. }
  186. void usnic_transport_fini(void)
  187. {
  188. kfree(roce_bitmap);
  189. }