netlink_conn.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. /****************************************************************************
  2. * net/netlink/netlink_conn.c
  3. *
  4. * Copyright (C) 2018 Gregory Nutt. All rights reserved.
  5. * Author: Gregory Nutt <gnutt@nuttx.org>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #include <stdint.h>
  40. #include <string.h>
  41. #include <assert.h>
  42. #include <errno.h>
  43. #include <debug.h>
  44. #include <arch/irq.h>
  45. #include <nuttx/semaphore.h>
  46. #include <nuttx/net/netconfig.h>
  47. #include <nuttx/net/net.h>
  48. #include "netlink/netlink.h"
  49. #ifdef CONFIG_NET_NETLINK
  50. /****************************************************************************
  51. * Private Data
  52. ****************************************************************************/
  53. /* The array containing all netlink connections. */
  54. static struct netlink_conn_s g_netlink_connections[CONFIG_NET_NETLINK_CONNS];
  55. /* A list of all free netlink connections */
  56. static dq_queue_t g_free_netlink_connections;
  57. static sem_t g_free_sem;
  58. /* A list of all allocated netlink connections */
  59. static dq_queue_t g_active_netlink_connections;
  60. /****************************************************************************
  61. * Private Functions
  62. ****************************************************************************/
  63. /****************************************************************************
  64. * Name: _netlink_semtake() and _netlink_semgive()
  65. *
  66. * Description:
  67. * Take/give semaphore
  68. *
  69. ****************************************************************************/
  70. static void _netlink_semtake(FAR sem_t *sem)
  71. {
  72. int ret;
  73. /* Take the semaphore (perhaps waiting) */
  74. while ((ret = net_lockedwait(sem)) < 0)
  75. {
  76. /* The only case that an error should occur here is if
  77. * the wait was awakened by a signal.
  78. */
  79. DEBUGASSERT(ret == -EINTR || ret == -ECANCELED);
  80. }
  81. }
  82. static void _netlink_semgive(FAR sem_t *sem)
  83. {
  84. (void)nxsem_post(sem);
  85. }
  86. /****************************************************************************
  87. * Public Functions
  88. ****************************************************************************/
  89. /****************************************************************************
  90. * Name: netlink_initialize()
  91. *
  92. * Description:
  93. * Initialize the User Socket connection structures. Called once and only
  94. * from the networking layer.
  95. *
  96. ****************************************************************************/
  97. void netlink_initialize(void)
  98. {
  99. int i;
  100. /* Initialize the queues */
  101. dq_init(&g_free_netlink_connections);
  102. dq_init(&g_active_netlink_connections);
  103. nxsem_init(&g_free_sem, 0, 1);
  104. for (i = 0; i < CONFIG_NET_NETLINK_CONNS; i++)
  105. {
  106. FAR struct netlink_conn_s *conn = &g_netlink_connections[i];
  107. /* Mark the connection closed and move it to the free list */
  108. memset(conn, 0, sizeof(*conn));
  109. dq_addlast(&conn->node, &g_free_netlink_connections);
  110. }
  111. }
  112. /****************************************************************************
  113. * Name: netlink_alloc()
  114. *
  115. * Description:
  116. * Allocate a new, uninitialized netlink connection structure. This is
  117. * normally something done by the implementation of the socket() API
  118. *
  119. ****************************************************************************/
  120. FAR struct netlink_conn_s *netlink_alloc(void)
  121. {
  122. FAR struct netlink_conn_s *conn;
  123. /* The free list is protected by a semaphore (that behaves like a mutex). */
  124. _netlink_semtake(&g_free_sem);
  125. conn = (FAR struct netlink_conn_s *)dq_remfirst(&g_free_netlink_connections);
  126. if (conn)
  127. {
  128. /* Make sure that the connection is marked as uninitialized */
  129. memset(conn, 0, sizeof(*conn));
  130. /* Enqueue the connection into the active list */
  131. dq_addlast(&conn->node, &g_active_netlink_connections);
  132. }
  133. _netlink_semgive(&g_free_sem);
  134. return conn;
  135. }
  136. /****************************************************************************
  137. * Name: netlink_free()
  138. *
  139. * Description:
  140. * Free a netlink connection structure that is no longer in use. This should
  141. * be done by the implementation of close().
  142. *
  143. ****************************************************************************/
  144. void netlink_free(FAR struct netlink_conn_s *conn)
  145. {
  146. /* The free list is protected by a semaphore (that behaves like a mutex). */
  147. DEBUGASSERT(conn->crefs == 0);
  148. _netlink_semtake(&g_free_sem);
  149. /* Remove the connection from the active list */
  150. dq_rem(&conn->node, &g_active_netlink_connections);
  151. /* Reset structure */
  152. memset(conn, 0, sizeof(*conn));
  153. /* Free the connection */
  154. dq_addlast(&conn->node, &g_free_netlink_connections);
  155. _netlink_semgive(&g_free_sem);
  156. }
  157. /****************************************************************************
  158. * Name: netlink_nextconn()
  159. *
  160. * Description:
  161. * Traverse the list of allocated netlink connections
  162. *
  163. * Assumptions:
  164. * This function is called from netlink device logic.
  165. *
  166. ****************************************************************************/
  167. FAR struct netlink_conn_s *netlink_nextconn(FAR struct netlink_conn_s *conn)
  168. {
  169. if (conn == NULL)
  170. {
  171. return (FAR struct netlink_conn_s *)g_active_netlink_connections.head;
  172. }
  173. else
  174. {
  175. return (FAR struct netlink_conn_s *)conn->node.flink;
  176. }
  177. }
  178. /****************************************************************************
  179. * Name: netlink_active()
  180. *
  181. * Description:
  182. * Find a connection structure that is the appropriate connection for the
  183. * provided netlink address
  184. *
  185. * Assumptions:
  186. *
  187. ****************************************************************************/
  188. FAR struct netlink_conn_s *netlink_active(FAR struct sockaddr_nl *addr)
  189. {
  190. FAR struct netlink_conn_s *conn = NULL;
  191. #warning "Missing logic for NETLINK active"
  192. return NULL;
  193. }
  194. #endif /* CONFIG_NET_NETLINK */