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 29illumos DDI Specific 30.Sh PARAMETERS 31.Bl -tag -width Fa 32.It Fa driver 33A pointer to the driver's private data that was passed in via the 34.Sy m_pdata 35member of the 36.Xr mac_register 9S 37structure to the 38.Xr mac_register 9F 39function. 40.It Fa add 41A boolean value that indicates whether the device driver should add the 42specified address to its filter list or remove it. 43.It Fa mac 44A pointer to an array of bytes that contains the new multicast address being 45added or removed. 46It is guaranteed to be at least a number of bytes long equal to the length of 47the MAC plugin's address length. 48For Ethernet devices that length is six bytes, 49.Sy ETHERADDRL . 50.El 51.Sh DESCRIPTION 52The 53.Fn mc_multicst 54entry point is used to program a device driver's multicast filters. 55For more background on filter management, see the 56.Sx MAC Address Filter Management 57section in 58.Xr mac 9E . 59.Pp 60The device driver can optionally sanity check 61.Fa mac 62by making sure that it's both a valid multicast address and by checking 63whether or not it's already programmed the address. 64Based on the value of 65.Fa add , 66the driver should either add the specified address, 67.Fa mac , 68or remove it from its filter tables. 69The device driver is not responsible for any form of reference counting on these 70requests: that is maintained by the broader framework. 71.Pp 72The device driver can access its own device soft state by casting the 73.Fa device 74pointer. 75The device driver should employ the appropriate locking while updating and 76manipulating its filter tables and its own records. 77It is recommended that device drivers always maintain a copy of the addresses 78programmed into the device's filter tables so that they can more easily 79recover from various device resets and errors, or handle requests to 80suspend and resume the device that may result in the device registers 81being cleared. 82.Sh RETURN VALUES 83Upon successful completion, the device driver should return 84.Sy 0 . 85Otherwise, the driver should return a positive error number to indicate 86why the request failed. 87.Sh EXAMPLES 88The following example shows how a device driver might structure its 89.Fn mc_multicst 90entry point. 91.Bd -literal 92#include <sys/mac_provider.h> 93 94/* 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 */ 103 104#define EXAMPLE_NMULTICAST_ADDRS 100 105 106static int 107example_multicast_add(example_t *ep, const uint8_t *mac_addr) 108{ 109 int i, ret; 110 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 } 123 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 } 132 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 } 144 145 mutex_exit(&ep->ep_lock); 146 147 return (ret); 148} 149 150static int 151example_multicast_remove(example_t *ep, const uint8_t *mac_addr) 152{ 153 int i, ret; 154 boolean_t found = B_FALSE; 155 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 } 164 165 if (found == B_FALSE) { 166 mutex_exit(&ep->ep_lock); 167 return (ENOENT); 168 } 169 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 } 188 189 mutex_exit(&ep->ep_lock); 190 return (ret); 191} 192 193static int 194example_m_multicst(void *arg, boolean_t add, const uint8_t *mac_addr) 195{ 196 example_t *ep = arg; 197 198 /* 199 * We sanity check that we've been given a multicast address. 200 */ 201 if ((mac_addr[0] & 0x01) == 0) 202 return (EINVAL); 203 204 if (add) 205 return (example_multicast_add(ep, mac_addr); 206 else 207 return (example_multicast_remove(ep, mac_addr)); 208} 209.Ed 210.Sh ERRORS 211The device driver may return one of the following errors. 212While this list is not intended to be exhaustive, it is recommended to use one 213of these if possible. 214.Bl -tag -width Er 215.It Er EINVAL 216The address 217.Fa mac 218is not a valid unicast address. 219.It Er EIO 220The driver encountered a device or transport error while trying to 221update the device's state. 222.It Er ENOENT 223The device driver was asked to remove a multicast address that it does 224not have. 225.It Er ENOSPC 226The driver was asked to add a multicast address; however, it has no more 227filter slots available to program the entry. 228.El 229.Sh SEE ALSO 230.Xr mac 9E , 231.Xr mac_register 9F , 232.Xr mac_register 9S 233