usnic_transport.c 5.0 KB

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