1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** NetX Component */
17 /** */
18 /** Internet Protocol (IPv6) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23
24 #define NX_SOURCE_CODE
25
26
27 /* Include necessary system files. */
28 #include "nx_api.h"
29 #include "nx_ipv6.h"
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _nxd_ipv6_multicast_interface_join PORTABLE C */
36 /* 6.1 */
37 /* AUTHOR */
38 /* */
39 /* Yuxin Zhou, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* This service allows an application to join a specific IPv6 */
44 /* multicast address on a specific physical interface. The link */
45 /* driver is notified to add the multicast address. */
46 /* */
47 /* INPUT */
48 /* */
49 /* ip_ptr IP instance pointer */
50 /* group_address IPv6 multicast address */
51 /* interface_index Index to the phyical interface*/
52 /* */
53 /* OUTPUT */
54 /* */
55 /* status Completion status */
56 /* */
57 /* CALLS */
58 /* */
59 /* tx_mutex_get Obtain protection mutex */
60 /* tx_mutex_put Release protection mutex */
61 /* memset Clear the memory */
62 /* (ip_link_driver) Device driver entry point */
63 /* CHECK_IPV6_ADDRESSES_SAME IPv6 address compare */
64 /* CHECK_UNSPECIFIED_ADDRESS Check for :: address */
65 /* */
66 /* CALLED BY */
67 /* */
68 /* Application */
69 /* */
70 /* RELEASE HISTORY */
71 /* */
72 /* DATE NAME DESCRIPTION */
73 /* */
74 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
75 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
76 /* resulting in version 6.1 */
77 /* */
78 /**************************************************************************/
_nxd_ipv6_multicast_interface_join(NX_IP * ip_ptr,NXD_ADDRESS * group_address,UINT interface_index)79 UINT _nxd_ipv6_multicast_interface_join(NX_IP *ip_ptr, NXD_ADDRESS *group_address, UINT interface_index)
80 {
81 #if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6)
82
83 UINT i;
84 UINT first_free;
85 NX_IP_DRIVER driver_request;
86 NX_INTERFACE *nx_interface;
87
88 /* Obtain the IP mutex so we can search the multicast join list. */
89 tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
90
91 nx_interface = &ip_ptr -> nx_ip_interface[interface_index];
92
93 /* Search the multicast join list for either the same group request. */
94 first_free = NX_MAX_MULTICAST_GROUPS;
95
96 for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++)
97 {
98
99 /* Determine if the specified entry is already in the multicast join list. */
100 if ((nx_interface == ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_interface_list) &&
101 (CHECK_IPV6_ADDRESSES_SAME(ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_list, group_address -> nxd_ip_address.v6)))
102 {
103
104 /* Yes, we have found the same entry. The only thing required in this
105 case is to increment the join count and return. */
106 ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_count++;
107
108 /* Release the IP protection. */
109 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
110
111 /* Return number of the group. */
112 return(NX_SUCCESS);
113 }
114
115 /* Check for an empty entry. */
116 if (CHECK_UNSPECIFIED_ADDRESS(ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_list) && (first_free == NX_MAX_MULTICAST_GROUPS))
117 {
118
119 /* Remember the first free entry. */
120 first_free = i;
121 }
122 }
123
124 /* At this point, we have a new entry. First, check to see if there is an available
125 entry. */
126 if (first_free == NX_MAX_MULTICAST_GROUPS)
127 {
128
129 /* Release the protection of the IP instance. */
130 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
131
132 /* Return an error code to indicate there are no more group addresses
133 available. */
134 return(NX_NO_MORE_ENTRIES);
135 }
136
137 /* Set it up in the IP control structures. */
138 ip_ptr -> nx_ipv6_multicast_entry[first_free].nx_ip_mld_join_list[0] = group_address -> nxd_ip_address.v6[0];
139 ip_ptr -> nx_ipv6_multicast_entry[first_free].nx_ip_mld_join_list[1] = group_address -> nxd_ip_address.v6[1];
140 ip_ptr -> nx_ipv6_multicast_entry[first_free].nx_ip_mld_join_list[2] = group_address -> nxd_ip_address.v6[2];
141 ip_ptr -> nx_ipv6_multicast_entry[first_free].nx_ip_mld_join_list[3] = group_address -> nxd_ip_address.v6[3];
142 ip_ptr -> nx_ipv6_multicast_entry[first_free].nx_ip_mld_join_interface_list = nx_interface;
143 ip_ptr -> nx_ipv6_multicast_entry[first_free].nx_ip_mld_join_count = 1;
144
145 /* Increment the MLD groups joined count. */
146 ip_ptr -> nx_ipv6_multicast_groups_joined++;
147
148 /* Register the new multicast group with the underlying driver to
149 ensure that there is room for the new group at the hardware level. */
150 driver_request.nx_ip_driver_ptr = ip_ptr;
151 driver_request.nx_ip_driver_command = NX_LINK_MULTICAST_JOIN;
152 driver_request.nx_ip_driver_physical_address_msw = 0x00003333;
153 driver_request.nx_ip_driver_physical_address_lsw = group_address -> nxd_ip_address.v6[3];
154 driver_request.nx_ip_driver_interface = nx_interface;
155
156 (nx_interface -> nx_interface_link_driver_entry)(&driver_request);
157
158 /* Check the return driver status. */
159 /*lint -e{644} suppress variable might not be initialized, since "nx_ip_driver_status" was initialized in nx_interface_link_driver_entry. */
160 if (driver_request.nx_ip_driver_status != NX_SUCCESS)
161 {
162
163 /* Release the protection of the IP instance. */
164 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
165
166 /* Return an error code to indicate there are no more group addresses
167 available. */
168 return(NX_OVERFLOW);
169 }
170
171 /* Release the protection over the IP instance. */
172 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
173
174 /* Return SUCCESS. */
175 return(NX_SUCCESS);
176
177 #else
178 NX_PARAMETER_NOT_USED(ip_ptr);
179 NX_PARAMETER_NOT_USED(group_address);
180 NX_PARAMETER_NOT_USED(interface_index);
181
182 return(NX_NOT_SUPPORTED);
183
184 #endif /* NX_ENABLE_IPV6_MULTICAST && FEATURE_NX_IPV6 */
185 }
186
187