1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Component */
16 /** */
17 /** Internet Protocol (IPv6) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "nx_api.h"
28 #include "nx_ipv6.h"
29
30
31 /**************************************************************************/
32 /* */
33 /* FUNCTION RELEASE */
34 /* */
35 /* _nxd_ipv6_multicast_interface_leave PORTABLE C */
36 /* 6.1 */
37 /* AUTHOR */
38 /* */
39 /* Yuxin Zhou, Microsoft Corporation */
40 /* */
41 /* DESCRIPTION */
42 /* */
43 /* This service removes the specific IPv6 multicast address from the */
44 /* sepcific physical interface. The link driver is also notified of */
45 /* the removal of the IPv6 multicast address. */
46 /* */
47 /* INPUT */
48 /* */
49 /* ip_ptr IP instance pointer */
50 /* group_address IPv6 multicast address */
51 /* interface_index Index to physical 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 /* */
64 /* CALLED BY */
65 /* */
66 /* Application */
67 /* */
68 /* RELEASE HISTORY */
69 /* */
70 /* DATE NAME DESCRIPTION */
71 /* */
72 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
73 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
74 /* resulting in version 6.1 */
75 /* */
76 /**************************************************************************/
_nxd_ipv6_multicast_interface_leave(NX_IP * ip_ptr,NXD_ADDRESS * group_address,UINT interface_index)77 UINT _nxd_ipv6_multicast_interface_leave(NX_IP *ip_ptr, NXD_ADDRESS *group_address, UINT interface_index)
78 {
79 #if defined(NX_ENABLE_IPV6_MULTICAST) && defined(FEATURE_NX_IPV6)
80
81 UINT i;
82 NX_IP_DRIVER driver_request;
83 NX_INTERFACE *nx_interface;
84
85 /* Obtain the IP mutex so we can search the multicast join list. */
86 tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
87
88 nx_interface = &ip_ptr -> nx_ip_interface[interface_index];
89
90 for (i = 0; i < NX_MAX_MULTICAST_GROUPS; i++)
91 {
92
93 /* Determine if the specified entry is present. */
94 if ((nx_interface == ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_interface_list) && (CHECK_IPV6_ADDRESSES_SAME(ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_list, group_address -> nxd_ip_address.v6)))
95 {
96
97 /* Yes, we have found the same entry. */
98
99 /* Decrease the join count. */
100 ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_count--;
101
102 /* Determine if there are no other join requests for this group address. */
103 if (ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_count == 0)
104 {
105
106 /* Clear the group join value. */
107 memset(ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_list, 0, 4 * sizeof(ULONG));
108
109 /* Decrement the MLD groups joined count. */
110 ip_ptr -> nx_ipv6_multicast_groups_joined--;
111
112 /* Un-register the new multicast group with the underlying driver. */
113 driver_request.nx_ip_driver_ptr = ip_ptr;
114 driver_request.nx_ip_driver_command = NX_LINK_MULTICAST_LEAVE;
115 driver_request.nx_ip_driver_physical_address_msw = 0x00003333;
116 driver_request.nx_ip_driver_physical_address_lsw = group_address -> nxd_ip_address.v6[3];
117 driver_request.nx_ip_driver_interface = nx_interface;
118
119 (ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_interface_list -> nx_interface_link_driver_entry)(&driver_request);
120
121 /* Now clear the interface entry. */
122 ip_ptr -> nx_ipv6_multicast_entry[i].nx_ip_mld_join_interface_list = NX_NULL;
123 }
124
125 /* Release the IP protection. */
126 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
127
128 /* Return success! */
129 return(NX_SUCCESS);
130 }
131 }
132
133 /* At this point we know that the supplied entry was not found. */
134
135 /* Release the protection of the IP instance. */
136 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
137
138 /* Return an error code. */
139 return(NX_ENTRY_NOT_FOUND);
140
141 #else
142 NX_PARAMETER_NOT_USED(ip_ptr);
143 NX_PARAMETER_NOT_USED(group_address);
144 NX_PARAMETER_NOT_USED(interface_index);
145
146 return(NX_NOT_SUPPORTED);
147
148 #endif /* NX_ENABLE_IPV6_MULTICAST && FEATURE_NX_IPV6 */
149 }
150
151