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. It is guaranteed to be at least a number of bytes long equal 46to the length of the MAC plugin's address length. For Ethernet devices that 47length is six bytes, 48.Sy ETHERADDRL . 49.El 50.Sh DESCRIPTION 51The 52.Fn mc_multicst 53entry point is used to program a device driver's multicast filters. For 54more background on filter management, see the 55.Sx MAC Address Filter Management 56section in 57.Xr mac 9E . 58.Pp 59The device driver can optionally sanity check 60.Fa mac 61by making sure that it's both a valid multicast address and by checking 62whether or not it's already programmed the address. Based on the value of 63.Fa add , 64the driver should either add the specified address, 65.Fa mac , 66or remove it from its filter tables. The device driver is not 67responsible for any form of reference counting on these requests: that 68is maintained by the broader framework. 69.Pp 70The device driver can access its own device soft state by casting the 71.Fa device 72pointer. The device driver should employ the appropriate locking while 73updating and manipulating its filter tables and its own records. It is 74recommended that device drivers always maintain a copy of the addresses 75programmed into the device's filter tables so that they can more easily 76recover from various device resets and errors, or handle requests to 77suspend and resume the device that may result in the device registers 78being cleared. 79.Sh RETURN VALUES 80Upon successful completion, the device driver should return 81.Sy 0 . 82Otherwise, the driver should return a positive error number to indicate 83why the request failed. 84.Sh EXAMPLES 85The following example shows how a device driver might structure its 86.Fn mc_multicst 87entry point. 88.Bd -literal 89#include <sys/mac_provider.h> 90 91/* 92 * Note, this example merely shows the structure of this function. 93 * Different devices will have different ways to manage the set of 94 * multicast MAC addresses that they can program into their filters and 95 * they have different ways of keeping track of them. Like other 96 * examples, this assumes that there is a lock which protects this data. 97 * In this case we assume we have an array of structures that is used to 98 * track each multicast entry and a count of valid entries. 99 */ 100 101#define EXAMPLE_NMULTICAST_ADDRS 100 102 103static int 104example_multicast_add(example_t *ep, const uint8_t *mac_addr) 105{ 106 int i, ret; 107 108 mutex_enter(&ep->ep_lock); 109 for (i = 0; i < ep->ep_nmcast_addrs; i++) { 110 if (bcmp(ep->ep_nmcast_addrs[i].ema_addr, mac_addr, 111 ETHERADDRL) == 0) { 112 /* 113 * The address is alread in our list, so we can 114 * return and say we're done. 115 */ 116 mutex_exit(&ep->ep_lock); 117 return (0); 118 } 119 } 120 121 /* 122 * We need to add this multicast address to a filter, make sure 123 * we have enough space to do so. 124 */ 125 if (ep->ep_nmcast_addrs >= EXAMPLE_NMULTICAST_ADDRS) { 126 mutex_exit(&ep->ep_lock); 127 return (ENOSPC); 128 } 129 130 /* 131 * Program the device before we add it to our list. Assume zero 132 * means success. 133 */ 134 ret = example_program_add_mcast_filter(ep, mac_addr); 135 if (ret == 0) { 136 bcopy(mac_addr, 137 ep->ep_nmcast_addrs[ep->ep_nmcast_addrs].ema_addr, 138 ETHERADDRL); 139 ep->ep_nmcast_addrs++; 140 } 141 142 mutex_exit(&ep->ep_lock); 143 144 return (ret); 145} 146 147static int 148example_multicast_remove(example_t *ep, const uint8_t *mac_addr) 149{ 150 int i, ret; 151 boolean_t found = B_FALSE; 152 153 mutex_enter(&ep->ep_lock); 154 for (i = 0; i < ep->ep_nmcast_addrs; i++) { 155 if (bcmp(ep->ep_mcast_addrs[i].ema_addr, mac_addr, 156 ETHERADDRL) == 0) { 157 found = B_TRUE; 158 break; 159 } 160 } 161 162 if (found == B_FALSE) { 163 mutex_exit(&ep->ep_lock); 164 return (ENOENT); 165 } 166 167 /* 168 * Assume that a return value of zero indicates that the removal 169 * was successful. Note that i still has the index of this 170 * entry. 171 */ 172 ret = example_program_rem_mcast_filter(ep, mac_addr); 173 if (ret == 0) { 174 int last = ep->ep_nmcast_addrs - 1; 175 if (i != last) { 176 bcopy(ep->ep_mcast_addrs[last].ema_addr, 177 ep->ep_mcast_addrs[i].ema_addr, 178 ETHERADDRL); 179 } 180 bzero(ep->ep_mcast_addrs[last].ema_addr, 181 ETHERADDRL); 182 VERIFY(ep->ep_nmcast_addrs > 0); 183 ep->ep_nmcast_addrs--; 184 } 185 186 mutex_exit(&ep->ep_lock); 187 return (ret); 188} 189 190static int 191example_m_multicst(void *arg, boolean_t add, const uint8_t *mac_addr) 192{ 193 example_t *ep = arg; 194 195 /* 196 * We sanity check that we've been given a multicast address. 197 */ 198 if ((mac_addr[0] & 0x01) == 0) 199 return (EINVAL); 200 201 if (add) 202 return (example_multicast_add(ep, mac_addr); 203 else 204 return (example_multicast_remove(ep, mac_addr)); 205} 206.Ed 207.Sh ERRORS 208The device driver may return one of the following errors. While this list 209is not intended to be exhaustive, it is recommended to use one of these 210if possible. 211.Bl -tag -width Er 212.It Er EINVAL 213The address 214.Fa mac 215is not a valid unicast address. 216.It Er EIO 217The driver encountered a device or transport error while trying to 218update the device's state. 219.It Er ENOENT 220The device driver was asked to remove a multicast address that it does 221not have. 222.It Er ENOSPC 223The driver was asked to add a multicast address; however, it has no more 224filter slots available to program the entry. 225.El 226.Sh SEE ALSO 227.Xr mac 9E , 228.Xr mac_register 9F , 229.Xr mac_register 9S 230