igmp_group.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /****************************************************************************
  2. * net/igmp/igmp_group.c
  3. * IGMP group data structure management logic
  4. *
  5. * Copyright (C) 2010, 2013-2014, 2016, 2018 Gregory Nutt. All rights reserved.
  6. * Author: Gregory Nutt <gnutt@nuttx.org>
  7. *
  8. * The NuttX implementation of IGMP was inspired by the IGMP add-on for the
  9. * lwIP TCP/IP stack by Steve Reynolds:
  10. *
  11. * Copyright (c) 2002 CITEL Technologies Ltd.
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions
  16. * are met:
  17. *
  18. * 1. Redistributions of source code must retain the above copyright
  19. * notice, this list of conditions and the following disclaimer.
  20. * 2. Redistributions in binary form must reproduce the above copyright
  21. * notice, this list of conditions and the following disclaimer in the
  22. * documentation and/or other materials provided with the distribution.
  23. * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors
  24. * may be used to endorse or promote products derived from this software
  25. * without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS''
  28. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  29. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  30. * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE
  31. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  33. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  34. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  36. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  37. * SUCH DAMAGE.
  38. *
  39. ****************************************************************************/
  40. /****************************************************************************
  41. * Included Files
  42. ****************************************************************************/
  43. #include <nuttx/config.h>
  44. #include <nuttx/compiler.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include <queue.h>
  48. #include <debug.h>
  49. #include <arch/irq.h>
  50. #include <nuttx/arch.h>
  51. #include <nuttx/wdog.h>
  52. #include <nuttx/kmalloc.h>
  53. #include <nuttx/semaphore.h>
  54. #include <nuttx/net/net.h>
  55. #include <nuttx/net/ip.h>
  56. #include <nuttx/net/igmp.h>
  57. #include "devif/devif.h"
  58. #include "igmp/igmp.h"
  59. #ifdef CONFIG_NET_IGMP
  60. /****************************************************************************
  61. * Pre-processor Definitions
  62. ****************************************************************************/
  63. /* Debug ********************************************************************/
  64. #undef IGMP_GRPDEBUG /* Define to enable detailed IGMP group debug */
  65. #ifndef CONFIG_NET_IGMP
  66. # undef IGMP_GRPDEBUG
  67. #endif
  68. #ifdef CONFIG_CPP_HAVE_VARARGS
  69. # ifdef IGMP_GRPDEBUG
  70. # define grperr(format, ...) nerr(format, ##__VA_ARGS__)
  71. # define grpinfo(format, ...) ninfo(format, ##__VA_ARGS__)
  72. # else
  73. # define grperr(x...)
  74. # define grpinfo(x...)
  75. # endif
  76. #else
  77. # ifdef IGMP_GRPDEBUG
  78. # define grperr nerr
  79. # define grpinfo ninfo
  80. # else
  81. # define grperr (void)
  82. # define grpinfo (void)
  83. # endif
  84. #endif
  85. /****************************************************************************
  86. * Public Functions
  87. ****************************************************************************/
  88. /****************************************************************************
  89. * Name: igmp_grpalloc
  90. *
  91. * Description:
  92. * Allocate a new group from heap memory.
  93. *
  94. * Assumptions:
  95. * The network is locked.
  96. *
  97. ****************************************************************************/
  98. FAR struct igmp_group_s *igmp_grpalloc(FAR struct net_driver_s *dev,
  99. FAR const in_addr_t *addr)
  100. {
  101. FAR struct igmp_group_s *group;
  102. ninfo("addr: %08x dev: %p\n", *addr, dev);
  103. group = (FAR struct igmp_group_s *)kmm_zalloc(sizeof(struct igmp_group_s));
  104. grpinfo("group: %p\n", group);
  105. /* Check if we successfully allocated a group structure */
  106. if (group != NULL)
  107. {
  108. /* Initialize the non-zero elements of the group structure */
  109. net_ipv4addr_copy(group->grpaddr, *addr);
  110. /* This semaphore is used for signaling and, hence, should not have
  111. * priority inheritance enabled.
  112. */
  113. nxsem_init(&group->sem, 0, 0);
  114. nxsem_setprotocol(&group->sem, SEM_PRIO_NONE);
  115. /* Initialize the group timer (but don't start it yet) */
  116. group->wdog = wd_create();
  117. DEBUGASSERT(group->wdog);
  118. /* Save the interface index */
  119. group->ifindex = dev->d_ifindex;
  120. /* Add the group structure to the list in the device structure */
  121. sq_addfirst((FAR sq_entry_t *)group, &dev->d_igmp_grplist);
  122. }
  123. return group;
  124. }
  125. /****************************************************************************
  126. * Name: igmp_grpfind
  127. *
  128. * Description:
  129. * Find an existing group.
  130. *
  131. * Assumptions:
  132. * The network is locked.
  133. *
  134. ****************************************************************************/
  135. FAR struct igmp_group_s *igmp_grpfind(FAR struct net_driver_s *dev,
  136. FAR const in_addr_t *addr)
  137. {
  138. FAR struct igmp_group_s *group;
  139. grpinfo("Searching for addr %08x\n", (int)*addr);
  140. for (group = (FAR struct igmp_group_s *)dev->d_igmp_grplist.head;
  141. group;
  142. group = group->next)
  143. {
  144. grpinfo("Compare: %08x vs. %08x\n", group->grpaddr, *addr);
  145. if (net_ipv4addr_cmp(group->grpaddr, *addr))
  146. {
  147. grpinfo("Match!\n");
  148. DEBUGASSERT(group->ifindex == dev->d_ifindex);
  149. break;
  150. }
  151. }
  152. return group;
  153. }
  154. /****************************************************************************
  155. * Name: igmp_grpallocfind
  156. *
  157. * Description:
  158. * Find an existing group. If not found, create a new group for the
  159. * address.
  160. *
  161. * Assumptions:
  162. * The network is locked.
  163. *
  164. ****************************************************************************/
  165. FAR struct igmp_group_s *igmp_grpallocfind(FAR struct net_driver_s *dev,
  166. FAR const in_addr_t *addr)
  167. {
  168. FAR struct igmp_group_s *group = igmp_grpfind(dev, addr);
  169. grpinfo("group: %p addr: %08x\n", group, (int)*addr);
  170. if (!group)
  171. {
  172. group = igmp_grpalloc(dev, addr);
  173. }
  174. grpinfo("group: %p\n", group);
  175. return group;
  176. }
  177. /****************************************************************************
  178. * Name: igmp_grpfree
  179. *
  180. * Description:
  181. * Release a previously allocated group.
  182. *
  183. * Assumptions:
  184. * The network is locked.
  185. *
  186. ****************************************************************************/
  187. void igmp_grpfree(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group)
  188. {
  189. grpinfo("Free: %p flags: %02x\n", group, group->flags);
  190. /* Cancel the wdog */
  191. wd_cancel(group->wdog);
  192. /* Remove the group structure from the group list in the device structure */
  193. sq_rem((FAR sq_entry_t *)group, &dev->d_igmp_grplist);
  194. /* Destroy the wait semaphore */
  195. (void)nxsem_destroy(&group->sem);
  196. /* Destroy the wdog */
  197. wd_delete(group->wdog);
  198. /* Then release the group structure resources. */
  199. grpinfo("Call sched_kfree()\n");
  200. sched_kfree(group);
  201. }
  202. #endif /* CONFIG_NET_IGMP */