8525 some more manpage spelling errors
[unleashed.git] / usr / src / man / man9e / mc_multicst.9e
blobdc0791f546b1846dec9cf77a2f9a0b39741ce78c
1 .\"
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
5 .\" 1.0 of the CDDL.
6 .\"
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.
10 .\"
11 .\"
12 .\" Copyright 2016 Joyent, Inc.
13 .\"
14 .Dd May 31, 2016
15 .Dt MC_MULTICST 9E
16 .Os
17 .Sh NAME
18 .Nm mc_multicst
19 .Nd add or remove multicast address from device filter
20 .Sh SYNOPSIS
21 .In sys/mac_provider.h
22 .Ft int
23 .Fo prefix_m_multicst
24 .Fa "void *driver"
25 .Fa "boolean_t add"
26 .Fa "const uint8_t *mac"
27 .Fc
28 .Sh INTERFACE LEVEL
29 illumos DDI Specific
30 .Sh PARAMETERS
31 .Bl -tag -width Fa
32 .It Fa driver
33 A pointer to the driver's private data that was passed in via the
34 .Sy m_pdata
35 member of the
36 .Xr mac_register 9S
37 structure to the
38 .Xr mac_register 9F
39 function.
40 .It Fa add
41 A boolean value that indicates whether the device driver should add the
42 specified address to its filter list or remove it.
43 .It Fa mac
44 A pointer to an array of bytes that contains the new multicast address being
45 added or removed.
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,
49 .Sy ETHERADDRL .
50 .El
51 .Sh DESCRIPTION
52 The
53 .Fn mc_multicst
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
57 section in
58 .Xr mac 9E .
59 .Pp
60 The device driver can optionally sanity check
61 .Fa mac
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.
64 Based on the value of
65 .Fa add ,
66 the driver should either add the specified address,
67 .Fa mac ,
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.
71 .Pp
72 The device driver can access its own device soft state by casting the
73 .Fa device
74 pointer.
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
81 being cleared.
82 .Sh RETURN VALUES
83 Upon successful completion, the device driver should return
84 .Sy 0 .
85 Otherwise, the driver should return a positive error number to indicate
86 why the request failed.
87 .Sh EXAMPLES
88 The following example shows how a device driver might structure its
89 .Fn mc_multicst
90 entry point.
91 .Bd -literal
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.
102  */
104 #define EXAMPLE_NMULTICAST_ADDRS        100
106 static int
107 example_multicast_add(example_t *ep, const uint8_t *mac_addr)
109         int i, ret;
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,
114                     ETHERADDRL) == 0) {
115                         /*
116                          * The address is alread in our list, so we can
117                          * return and say we're done.
118                          */
119                         mutex_exit(&ep->ep_lock);
120                         return (0);
121                 }
122         }
124         /*
125          * We need to add this multicast address to a filter, make sure
126          * we have enough space to do so.
127          */
128         if (ep->ep_nmcast_addrs >= EXAMPLE_NMULTICAST_ADDRS) {
129                 mutex_exit(&ep->ep_lock);
130                 return (ENOSPC);
131         }
133         /*
134          * Program the device before we add it to our list. Assume zero
135          * means success.
136          */
137         ret = example_program_add_mcast_filter(ep, mac_addr);
138         if (ret == 0) {
139                 bcopy(mac_addr,
140                     ep->ep_nmcast_addrs[ep->ep_nmcast_addrs].ema_addr,
141                     ETHERADDRL);
142                 ep->ep_nmcast_addrs++;
143         }
145         mutex_exit(&ep->ep_lock);
147         return (ret);
150 static int
151 example_multicast_remove(example_t *ep, const uint8_t *mac_addr)
153         int i, ret;
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,
159                     ETHERADDRL) == 0) {
160                         found = B_TRUE;
161                         break;
162                 }
163         }
165         if (found == B_FALSE) {
166                 mutex_exit(&ep->ep_lock);
167                 return (ENOENT);
168         }
170         /*
171          * Assume that a return value of zero indicates that the removal
172          * was successful. Note that i still has the index of this
173          * entry.
174          */
175         ret = example_program_rem_mcast_filter(ep, mac_addr);
176         if (ret == 0) {
177                 int last = ep->ep_nmcast_addrs - 1;
178                 if (i != last) {
179                         bcopy(ep->ep_mcast_addrs[last].ema_addr,
180                             ep->ep_mcast_addrs[i].ema_addr,
181                             ETHERADDRL);
182                 }
183                 bzero(ep->ep_mcast_addrs[last].ema_addr,
184                     ETHERADDRL);
185                 VERIFY(ep->ep_nmcast_addrs > 0);
186                 ep->ep_nmcast_addrs--;
187         }
189         mutex_exit(&ep->ep_lock);
190         return (ret);
193 static int
194 example_m_multicst(void *arg, boolean_t add, const uint8_t *mac_addr)
196         example_t *ep = arg;
198         /*
199          * We sanity check that we've been given a multicast address.
200          */
201         if ((mac_addr[0] & 0x01) == 0)
202                 return (EINVAL);
204         if (add)
205                 return (example_multicast_add(ep, mac_addr);
206         else
207                 return (example_multicast_remove(ep, mac_addr));
210 .Sh ERRORS
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.
214 .Bl -tag -width Er
215 .It Er EINVAL
216 The address
217 .Fa mac
218 is not a valid unicast address.
219 .It Er EIO
220 The driver encountered a device or transport error while trying to
221 update the device's state.
222 .It Er ENOENT
223 The device driver was asked to remove a multicast address that it does
224 not have.
225 .It Er ENOSPC
226 The driver was asked to add a multicast address; however, it has no more
227 filter slots available to program the entry.
229 .Sh SEE ALSO
230 .Xr mac 9E ,
231 .Xr mac_register 9F ,
232 .Xr mac_register 9S