2 .\" This file and its contents are supplied under the terms of the
3 .\" Common Development and Distribution License ("CDDL"), version 1.0.
4 .\" You may only use this file in accordance with the terms of version
7 .\" A full copy of the text of the CDDL should have accompanied this
8 .\" source. A copy of the CDDL is also available via the Internet at
9 .\" http://www.illumos.org/license/CDDL.
12 .\" Copyright 2016 Joyent, Inc.
19 .Nd add or remove multicast address from device filter
21 .In sys/mac_provider.h
26 .Fa "const uint8_t *mac"
33 A pointer to the driver's private data that was passed in via the
41 A boolean value that indicates whether the device driver should add the
42 specified address to its filter list or remove it.
44 A pointer to an array of bytes that contains the new multicast address being
46 It is guaranteed to be at least a number of bytes long equal to the length of
47 the MAC plugin's address length.
48 For Ethernet devices that length is six bytes,
54 entry point is used to program a device driver's multicast filters.
55 For more background on filter management, see the
56 .Sx MAC Address Filter Management
60 The device driver can optionally sanity check
62 by making sure that it's both a valid multicast address and by checking
63 whether or not it's already programmed the address.
66 the driver should either add the specified address,
68 or remove it from its filter tables.
69 The device driver is not responsible for any form of reference counting on these
70 requests: that is maintained by the broader framework.
72 The device driver can access its own device soft state by casting the
75 The device driver should employ the appropriate locking while updating and
76 manipulating its filter tables and its own records.
77 It is recommended that device drivers always maintain a copy of the addresses
78 programmed into the device's filter tables so that they can more easily
79 recover from various device resets and errors, or handle requests to
80 suspend and resume the device that may result in the device registers
83 Upon successful completion, the device driver should return
85 Otherwise, the driver should return a positive error number to indicate
86 why the request failed.
88 The following example shows how a device driver might structure its
92 #include <sys/mac_provider.h>
95 * Note, this example merely shows the structure of this function.
96 * Different devices will have different ways to manage the set of
97 * multicast MAC addresses that they can program into their filters and
98 * they have different ways of keeping track of them. Like other
99 * examples, this assumes that there is a lock which protects this data.
100 * In this case we assume we have an array of structures that is used to
101 * track each multicast entry and a count of valid entries.
104 #define EXAMPLE_NMULTICAST_ADDRS 100
107 example_multicast_add(example_t *ep, const uint8_t *mac_addr)
111 mutex_enter(&ep->ep_lock);
112 for (i = 0; i < ep->ep_nmcast_addrs; i++) {
113 if (bcmp(ep->ep_nmcast_addrs[i].ema_addr, mac_addr,
116 * The address is alread in our list, so we can
117 * return and say we're done.
119 mutex_exit(&ep->ep_lock);
125 * We need to add this multicast address to a filter, make sure
126 * we have enough space to do so.
128 if (ep->ep_nmcast_addrs >= EXAMPLE_NMULTICAST_ADDRS) {
129 mutex_exit(&ep->ep_lock);
134 * Program the device before we add it to our list. Assume zero
137 ret = example_program_add_mcast_filter(ep, mac_addr);
140 ep->ep_nmcast_addrs[ep->ep_nmcast_addrs].ema_addr,
142 ep->ep_nmcast_addrs++;
145 mutex_exit(&ep->ep_lock);
151 example_multicast_remove(example_t *ep, const uint8_t *mac_addr)
154 boolean_t found = B_FALSE;
156 mutex_enter(&ep->ep_lock);
157 for (i = 0; i < ep->ep_nmcast_addrs; i++) {
158 if (bcmp(ep->ep_mcast_addrs[i].ema_addr, mac_addr,
165 if (found == B_FALSE) {
166 mutex_exit(&ep->ep_lock);
171 * Assume that a return value of zero indicates that the removal
172 * was successful. Note that i still has the index of this
175 ret = example_program_rem_mcast_filter(ep, mac_addr);
177 int last = ep->ep_nmcast_addrs - 1;
179 bcopy(ep->ep_mcast_addrs[last].ema_addr,
180 ep->ep_mcast_addrs[i].ema_addr,
183 bzero(ep->ep_mcast_addrs[last].ema_addr,
185 VERIFY(ep->ep_nmcast_addrs > 0);
186 ep->ep_nmcast_addrs--;
189 mutex_exit(&ep->ep_lock);
194 example_m_multicst(void *arg, boolean_t add, const uint8_t *mac_addr)
199 * We sanity check that we've been given a multicast address.
201 if ((mac_addr[0] & 0x01) == 0)
205 return (example_multicast_add(ep, mac_addr);
207 return (example_multicast_remove(ep, mac_addr));
211 The device driver may return one of the following errors.
212 While this list is not intended to be exhaustive, it is recommended to use one
213 of these if possible.
218 is not a valid unicast address.
220 The driver encountered a device or transport error while trying to
221 update the device's state.
223 The device driver was asked to remove a multicast address that it does
226 The driver was asked to add a multicast address; however, it has no more
227 filter slots available to program the entry.
231 .Xr mac_register 9F ,