Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * net/core/dev_addr_lists.c - Functions for handling net device lists
4 : * Copyright (c) 2010 Jiri Pirko <jpirko@redhat.com>
5 : *
6 : * This file contains functions for working with unicast, multicast and device
7 : * addresses lists.
8 : */
9 :
10 : #include <linux/netdevice.h>
11 : #include <linux/rtnetlink.h>
12 : #include <linux/export.h>
13 : #include <linux/list.h>
14 :
15 : /*
16 : * General list handling functions
17 : */
18 :
19 4 : static int __hw_addr_create_ex(struct netdev_hw_addr_list *list,
20 : const unsigned char *addr, int addr_len,
21 : unsigned char addr_type, bool global,
22 : bool sync)
23 : {
24 4 : struct netdev_hw_addr *ha;
25 4 : int alloc_size;
26 :
27 4 : alloc_size = sizeof(*ha);
28 4 : if (alloc_size < L1_CACHE_BYTES)
29 : alloc_size = L1_CACHE_BYTES;
30 4 : ha = kmalloc(alloc_size, GFP_ATOMIC);
31 4 : if (!ha)
32 : return -ENOMEM;
33 4 : memcpy(ha->addr, addr, addr_len);
34 4 : ha->type = addr_type;
35 4 : ha->refcount = 1;
36 4 : ha->global_use = global;
37 4 : ha->synced = sync ? 1 : 0;
38 4 : ha->sync_cnt = 0;
39 4 : list_add_tail_rcu(&ha->list, &list->list);
40 4 : list->count++;
41 :
42 4 : return 0;
43 : }
44 :
45 4 : static int __hw_addr_add_ex(struct netdev_hw_addr_list *list,
46 : const unsigned char *addr, int addr_len,
47 : unsigned char addr_type, bool global, bool sync,
48 : int sync_count)
49 : {
50 4 : struct netdev_hw_addr *ha;
51 :
52 4 : if (addr_len > MAX_ADDR_LEN)
53 : return -EINVAL;
54 :
55 4 : list_for_each_entry(ha, &list->list, list) {
56 0 : if (ha->type == addr_type &&
57 0 : !memcmp(ha->addr, addr, addr_len)) {
58 0 : if (global) {
59 : /* check if addr is already used as global */
60 0 : if (ha->global_use)
61 : return 0;
62 : else
63 0 : ha->global_use = true;
64 : }
65 0 : if (sync) {
66 0 : if (ha->synced && sync_count)
67 : return -EEXIST;
68 : else
69 0 : ha->synced++;
70 : }
71 0 : ha->refcount++;
72 0 : return 0;
73 : }
74 : }
75 :
76 4 : return __hw_addr_create_ex(list, addr, addr_len, addr_type, global,
77 : sync);
78 : }
79 :
80 3 : static int __hw_addr_add(struct netdev_hw_addr_list *list,
81 : const unsigned char *addr, int addr_len,
82 : unsigned char addr_type)
83 : {
84 3 : return __hw_addr_add_ex(list, addr, addr_len, addr_type, false, false,
85 : 0);
86 : }
87 :
88 0 : static int __hw_addr_del_entry(struct netdev_hw_addr_list *list,
89 : struct netdev_hw_addr *ha, bool global,
90 : bool sync)
91 : {
92 0 : if (global && !ha->global_use)
93 : return -ENOENT;
94 :
95 0 : if (sync && !ha->synced)
96 : return -ENOENT;
97 :
98 0 : if (global)
99 0 : ha->global_use = false;
100 :
101 0 : if (sync)
102 0 : ha->synced--;
103 :
104 0 : if (--ha->refcount)
105 : return 0;
106 0 : list_del_rcu(&ha->list);
107 0 : kfree_rcu(ha, rcu_head);
108 0 : list->count--;
109 0 : return 0;
110 : }
111 :
112 0 : static int __hw_addr_del_ex(struct netdev_hw_addr_list *list,
113 : const unsigned char *addr, int addr_len,
114 : unsigned char addr_type, bool global, bool sync)
115 : {
116 0 : struct netdev_hw_addr *ha;
117 :
118 0 : list_for_each_entry(ha, &list->list, list) {
119 0 : if (!memcmp(ha->addr, addr, addr_len) &&
120 0 : (ha->type == addr_type || !addr_type))
121 0 : return __hw_addr_del_entry(list, ha, global, sync);
122 : }
123 : return -ENOENT;
124 : }
125 :
126 0 : static int __hw_addr_del(struct netdev_hw_addr_list *list,
127 : const unsigned char *addr, int addr_len,
128 : unsigned char addr_type)
129 : {
130 0 : return __hw_addr_del_ex(list, addr, addr_len, addr_type, false, false);
131 : }
132 :
133 0 : static int __hw_addr_sync_one(struct netdev_hw_addr_list *to_list,
134 : struct netdev_hw_addr *ha,
135 : int addr_len)
136 : {
137 0 : int err;
138 :
139 0 : err = __hw_addr_add_ex(to_list, ha->addr, addr_len, ha->type,
140 : false, true, ha->sync_cnt);
141 0 : if (err && err != -EEXIST)
142 : return err;
143 :
144 0 : if (!err) {
145 0 : ha->sync_cnt++;
146 0 : ha->refcount++;
147 : }
148 :
149 : return 0;
150 : }
151 :
152 0 : static void __hw_addr_unsync_one(struct netdev_hw_addr_list *to_list,
153 : struct netdev_hw_addr_list *from_list,
154 : struct netdev_hw_addr *ha,
155 : int addr_len)
156 : {
157 0 : int err;
158 :
159 0 : err = __hw_addr_del_ex(to_list, ha->addr, addr_len, ha->type,
160 : false, true);
161 0 : if (err)
162 : return;
163 0 : ha->sync_cnt--;
164 : /* address on from list is not marked synced */
165 0 : __hw_addr_del_entry(from_list, ha, false, false);
166 : }
167 :
168 0 : static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list,
169 : struct netdev_hw_addr_list *from_list,
170 : int addr_len)
171 : {
172 0 : int err = 0;
173 0 : struct netdev_hw_addr *ha, *tmp;
174 :
175 0 : list_for_each_entry_safe(ha, tmp, &from_list->list, list) {
176 0 : if (ha->sync_cnt == ha->refcount) {
177 0 : __hw_addr_unsync_one(to_list, from_list, ha, addr_len);
178 : } else {
179 0 : err = __hw_addr_sync_one(to_list, ha, addr_len);
180 0 : if (err)
181 : break;
182 : }
183 : }
184 0 : return err;
185 : }
186 :
187 : /* This function only works where there is a strict 1-1 relationship
188 : * between source and destionation of they synch. If you ever need to
189 : * sync addresses to more then 1 destination, you need to use
190 : * __hw_addr_sync_multiple().
191 : */
192 0 : int __hw_addr_sync(struct netdev_hw_addr_list *to_list,
193 : struct netdev_hw_addr_list *from_list,
194 : int addr_len)
195 : {
196 0 : int err = 0;
197 0 : struct netdev_hw_addr *ha, *tmp;
198 :
199 0 : list_for_each_entry_safe(ha, tmp, &from_list->list, list) {
200 0 : if (!ha->sync_cnt) {
201 0 : err = __hw_addr_sync_one(to_list, ha, addr_len);
202 0 : if (err)
203 : break;
204 0 : } else if (ha->refcount == 1)
205 0 : __hw_addr_unsync_one(to_list, from_list, ha, addr_len);
206 : }
207 0 : return err;
208 : }
209 : EXPORT_SYMBOL(__hw_addr_sync);
210 :
211 0 : void __hw_addr_unsync(struct netdev_hw_addr_list *to_list,
212 : struct netdev_hw_addr_list *from_list,
213 : int addr_len)
214 : {
215 0 : struct netdev_hw_addr *ha, *tmp;
216 :
217 0 : list_for_each_entry_safe(ha, tmp, &from_list->list, list) {
218 0 : if (ha->sync_cnt)
219 0 : __hw_addr_unsync_one(to_list, from_list, ha, addr_len);
220 : }
221 0 : }
222 : EXPORT_SYMBOL(__hw_addr_unsync);
223 :
224 : /**
225 : * __hw_addr_sync_dev - Synchonize device's multicast list
226 : * @list: address list to syncronize
227 : * @dev: device to sync
228 : * @sync: function to call if address should be added
229 : * @unsync: function to call if address should be removed
230 : *
231 : * This funciton is intended to be called from the ndo_set_rx_mode
232 : * function of devices that require explicit address add/remove
233 : * notifications. The unsync function may be NULL in which case
234 : * the addresses requiring removal will simply be removed without
235 : * any notification to the device.
236 : **/
237 0 : int __hw_addr_sync_dev(struct netdev_hw_addr_list *list,
238 : struct net_device *dev,
239 : int (*sync)(struct net_device *, const unsigned char *),
240 : int (*unsync)(struct net_device *,
241 : const unsigned char *))
242 : {
243 0 : struct netdev_hw_addr *ha, *tmp;
244 0 : int err;
245 :
246 : /* first go through and flush out any stale entries */
247 0 : list_for_each_entry_safe(ha, tmp, &list->list, list) {
248 0 : if (!ha->sync_cnt || ha->refcount != 1)
249 0 : continue;
250 :
251 : /* if unsync is defined and fails defer unsyncing address */
252 0 : if (unsync && unsync(dev, ha->addr))
253 0 : continue;
254 :
255 0 : ha->sync_cnt--;
256 0 : __hw_addr_del_entry(list, ha, false, false);
257 : }
258 :
259 : /* go through and sync new entries to the list */
260 0 : list_for_each_entry_safe(ha, tmp, &list->list, list) {
261 0 : if (ha->sync_cnt)
262 0 : continue;
263 :
264 0 : err = sync(dev, ha->addr);
265 0 : if (err)
266 0 : return err;
267 :
268 0 : ha->sync_cnt++;
269 0 : ha->refcount++;
270 : }
271 :
272 : return 0;
273 : }
274 : EXPORT_SYMBOL(__hw_addr_sync_dev);
275 :
276 : /**
277 : * __hw_addr_ref_sync_dev - Synchronize device's multicast address list taking
278 : * into account references
279 : * @list: address list to synchronize
280 : * @dev: device to sync
281 : * @sync: function to call if address or reference on it should be added
282 : * @unsync: function to call if address or some reference on it should removed
283 : *
284 : * This function is intended to be called from the ndo_set_rx_mode
285 : * function of devices that require explicit address or references on it
286 : * add/remove notifications. The unsync function may be NULL in which case
287 : * the addresses or references on it requiring removal will simply be
288 : * removed without any notification to the device. That is responsibility of
289 : * the driver to identify and distribute address or references on it between
290 : * internal address tables.
291 : **/
292 0 : int __hw_addr_ref_sync_dev(struct netdev_hw_addr_list *list,
293 : struct net_device *dev,
294 : int (*sync)(struct net_device *,
295 : const unsigned char *, int),
296 : int (*unsync)(struct net_device *,
297 : const unsigned char *, int))
298 : {
299 0 : struct netdev_hw_addr *ha, *tmp;
300 0 : int err, ref_cnt;
301 :
302 : /* first go through and flush out any unsynced/stale entries */
303 0 : list_for_each_entry_safe(ha, tmp, &list->list, list) {
304 : /* sync if address is not used */
305 0 : if ((ha->sync_cnt << 1) <= ha->refcount)
306 0 : continue;
307 :
308 : /* if fails defer unsyncing address */
309 0 : ref_cnt = ha->refcount - ha->sync_cnt;
310 0 : if (unsync && unsync(dev, ha->addr, ref_cnt))
311 0 : continue;
312 :
313 0 : ha->refcount = (ref_cnt << 1) + 1;
314 0 : ha->sync_cnt = ref_cnt;
315 0 : __hw_addr_del_entry(list, ha, false, false);
316 : }
317 :
318 : /* go through and sync updated/new entries to the list */
319 0 : list_for_each_entry_safe(ha, tmp, &list->list, list) {
320 : /* sync if address added or reused */
321 0 : if ((ha->sync_cnt << 1) >= ha->refcount)
322 0 : continue;
323 :
324 0 : ref_cnt = ha->refcount - ha->sync_cnt;
325 0 : err = sync(dev, ha->addr, ref_cnt);
326 0 : if (err)
327 0 : return err;
328 :
329 0 : ha->refcount = ref_cnt << 1;
330 0 : ha->sync_cnt = ref_cnt;
331 : }
332 :
333 : return 0;
334 : }
335 : EXPORT_SYMBOL(__hw_addr_ref_sync_dev);
336 :
337 : /**
338 : * __hw_addr_ref_unsync_dev - Remove synchronized addresses and references on
339 : * it from device
340 : * @list: address list to remove synchronized addresses (references on it) from
341 : * @dev: device to sync
342 : * @unsync: function to call if address and references on it should be removed
343 : *
344 : * Remove all addresses that were added to the device by
345 : * __hw_addr_ref_sync_dev(). This function is intended to be called from the
346 : * ndo_stop or ndo_open functions on devices that require explicit address (or
347 : * references on it) add/remove notifications. If the unsync function pointer
348 : * is NULL then this function can be used to just reset the sync_cnt for the
349 : * addresses in the list.
350 : **/
351 0 : void __hw_addr_ref_unsync_dev(struct netdev_hw_addr_list *list,
352 : struct net_device *dev,
353 : int (*unsync)(struct net_device *,
354 : const unsigned char *, int))
355 : {
356 0 : struct netdev_hw_addr *ha, *tmp;
357 :
358 0 : list_for_each_entry_safe(ha, tmp, &list->list, list) {
359 0 : if (!ha->sync_cnt)
360 0 : continue;
361 :
362 : /* if fails defer unsyncing address */
363 0 : if (unsync && unsync(dev, ha->addr, ha->sync_cnt))
364 0 : continue;
365 :
366 0 : ha->refcount -= ha->sync_cnt - 1;
367 0 : ha->sync_cnt = 0;
368 0 : __hw_addr_del_entry(list, ha, false, false);
369 : }
370 0 : }
371 : EXPORT_SYMBOL(__hw_addr_ref_unsync_dev);
372 :
373 : /**
374 : * __hw_addr_unsync_dev - Remove synchronized addresses from device
375 : * @list: address list to remove synchronized addresses from
376 : * @dev: device to sync
377 : * @unsync: function to call if address should be removed
378 : *
379 : * Remove all addresses that were added to the device by __hw_addr_sync_dev().
380 : * This function is intended to be called from the ndo_stop or ndo_open
381 : * functions on devices that require explicit address add/remove
382 : * notifications. If the unsync function pointer is NULL then this function
383 : * can be used to just reset the sync_cnt for the addresses in the list.
384 : **/
385 0 : void __hw_addr_unsync_dev(struct netdev_hw_addr_list *list,
386 : struct net_device *dev,
387 : int (*unsync)(struct net_device *,
388 : const unsigned char *))
389 : {
390 0 : struct netdev_hw_addr *ha, *tmp;
391 :
392 0 : list_for_each_entry_safe(ha, tmp, &list->list, list) {
393 0 : if (!ha->sync_cnt)
394 0 : continue;
395 :
396 : /* if unsync is defined and fails defer unsyncing address */
397 0 : if (unsync && unsync(dev, ha->addr))
398 0 : continue;
399 :
400 0 : ha->sync_cnt--;
401 0 : __hw_addr_del_entry(list, ha, false, false);
402 : }
403 0 : }
404 : EXPORT_SYMBOL(__hw_addr_unsync_dev);
405 :
406 0 : static void __hw_addr_flush(struct netdev_hw_addr_list *list)
407 : {
408 0 : struct netdev_hw_addr *ha, *tmp;
409 :
410 0 : list_for_each_entry_safe(ha, tmp, &list->list, list) {
411 0 : list_del_rcu(&ha->list);
412 0 : kfree_rcu(ha, rcu_head);
413 : }
414 0 : list->count = 0;
415 0 : }
416 :
417 9 : void __hw_addr_init(struct netdev_hw_addr_list *list)
418 : {
419 9 : INIT_LIST_HEAD(&list->list);
420 9 : list->count = 0;
421 0 : }
422 : EXPORT_SYMBOL(__hw_addr_init);
423 :
424 : /*
425 : * Device addresses handling functions
426 : */
427 :
428 : /**
429 : * dev_addr_flush - Flush device address list
430 : * @dev: device
431 : *
432 : * Flush device address list and reset ->dev_addr.
433 : *
434 : * The caller must hold the rtnl_mutex.
435 : */
436 0 : void dev_addr_flush(struct net_device *dev)
437 : {
438 : /* rtnl_mutex must be held here */
439 :
440 0 : __hw_addr_flush(&dev->dev_addrs);
441 0 : dev->dev_addr = NULL;
442 0 : }
443 : EXPORT_SYMBOL(dev_addr_flush);
444 :
445 : /**
446 : * dev_addr_init - Init device address list
447 : * @dev: device
448 : *
449 : * Init device address list and create the first element,
450 : * used by ->dev_addr.
451 : *
452 : * The caller must hold the rtnl_mutex.
453 : */
454 3 : int dev_addr_init(struct net_device *dev)
455 : {
456 3 : unsigned char addr[MAX_ADDR_LEN];
457 3 : struct netdev_hw_addr *ha;
458 3 : int err;
459 :
460 : /* rtnl_mutex must be held here */
461 :
462 3 : __hw_addr_init(&dev->dev_addrs);
463 3 : memset(addr, 0, sizeof(addr));
464 3 : err = __hw_addr_add(&dev->dev_addrs, addr, sizeof(addr),
465 : NETDEV_HW_ADDR_T_LAN);
466 3 : if (!err) {
467 : /*
468 : * Get the first (previously created) address from the list
469 : * and set dev_addr pointer to this location.
470 : */
471 3 : ha = list_first_entry(&dev->dev_addrs.list,
472 : struct netdev_hw_addr, list);
473 3 : dev->dev_addr = ha->addr;
474 : }
475 3 : return err;
476 : }
477 : EXPORT_SYMBOL(dev_addr_init);
478 :
479 : /**
480 : * dev_addr_add - Add a device address
481 : * @dev: device
482 : * @addr: address to add
483 : * @addr_type: address type
484 : *
485 : * Add a device address to the device or increase the reference count if
486 : * it already exists.
487 : *
488 : * The caller must hold the rtnl_mutex.
489 : */
490 0 : int dev_addr_add(struct net_device *dev, const unsigned char *addr,
491 : unsigned char addr_type)
492 : {
493 0 : int err;
494 :
495 0 : ASSERT_RTNL();
496 :
497 0 : err = dev_pre_changeaddr_notify(dev, addr, NULL);
498 0 : if (err)
499 : return err;
500 0 : err = __hw_addr_add(&dev->dev_addrs, addr, dev->addr_len, addr_type);
501 0 : if (!err)
502 0 : call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
503 : return err;
504 : }
505 : EXPORT_SYMBOL(dev_addr_add);
506 :
507 : /**
508 : * dev_addr_del - Release a device address.
509 : * @dev: device
510 : * @addr: address to delete
511 : * @addr_type: address type
512 : *
513 : * Release reference to a device address and remove it from the device
514 : * if the reference count drops to zero.
515 : *
516 : * The caller must hold the rtnl_mutex.
517 : */
518 0 : int dev_addr_del(struct net_device *dev, const unsigned char *addr,
519 : unsigned char addr_type)
520 : {
521 0 : int err;
522 0 : struct netdev_hw_addr *ha;
523 :
524 0 : ASSERT_RTNL();
525 :
526 : /*
527 : * We can not remove the first address from the list because
528 : * dev->dev_addr points to that.
529 : */
530 0 : ha = list_first_entry(&dev->dev_addrs.list,
531 : struct netdev_hw_addr, list);
532 0 : if (!memcmp(ha->addr, addr, dev->addr_len) &&
533 0 : ha->type == addr_type && ha->refcount == 1)
534 : return -ENOENT;
535 :
536 0 : err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len,
537 : addr_type);
538 0 : if (!err)
539 0 : call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
540 : return err;
541 : }
542 : EXPORT_SYMBOL(dev_addr_del);
543 :
544 : /*
545 : * Unicast list handling functions
546 : */
547 :
548 : /**
549 : * dev_uc_add_excl - Add a global secondary unicast address
550 : * @dev: device
551 : * @addr: address to add
552 : */
553 0 : int dev_uc_add_excl(struct net_device *dev, const unsigned char *addr)
554 : {
555 0 : struct netdev_hw_addr *ha;
556 0 : int err;
557 :
558 0 : netif_addr_lock_bh(dev);
559 0 : list_for_each_entry(ha, &dev->uc.list, list) {
560 0 : if (!memcmp(ha->addr, addr, dev->addr_len) &&
561 0 : ha->type == NETDEV_HW_ADDR_T_UNICAST) {
562 0 : err = -EEXIST;
563 0 : goto out;
564 : }
565 : }
566 0 : err = __hw_addr_create_ex(&dev->uc, addr, dev->addr_len,
567 : NETDEV_HW_ADDR_T_UNICAST, true, false);
568 0 : if (!err)
569 0 : __dev_set_rx_mode(dev);
570 0 : out:
571 0 : netif_addr_unlock_bh(dev);
572 0 : return err;
573 : }
574 : EXPORT_SYMBOL(dev_uc_add_excl);
575 :
576 : /**
577 : * dev_uc_add - Add a secondary unicast address
578 : * @dev: device
579 : * @addr: address to add
580 : *
581 : * Add a secondary unicast address to the device or increase
582 : * the reference count if it already exists.
583 : */
584 0 : int dev_uc_add(struct net_device *dev, const unsigned char *addr)
585 : {
586 0 : int err;
587 :
588 0 : netif_addr_lock_bh(dev);
589 0 : err = __hw_addr_add(&dev->uc, addr, dev->addr_len,
590 : NETDEV_HW_ADDR_T_UNICAST);
591 0 : if (!err)
592 0 : __dev_set_rx_mode(dev);
593 0 : netif_addr_unlock_bh(dev);
594 0 : return err;
595 : }
596 : EXPORT_SYMBOL(dev_uc_add);
597 :
598 : /**
599 : * dev_uc_del - Release secondary unicast address.
600 : * @dev: device
601 : * @addr: address to delete
602 : *
603 : * Release reference to a secondary unicast address and remove it
604 : * from the device if the reference count drops to zero.
605 : */
606 0 : int dev_uc_del(struct net_device *dev, const unsigned char *addr)
607 : {
608 0 : int err;
609 :
610 0 : netif_addr_lock_bh(dev);
611 0 : err = __hw_addr_del(&dev->uc, addr, dev->addr_len,
612 : NETDEV_HW_ADDR_T_UNICAST);
613 0 : if (!err)
614 0 : __dev_set_rx_mode(dev);
615 0 : netif_addr_unlock_bh(dev);
616 0 : return err;
617 : }
618 : EXPORT_SYMBOL(dev_uc_del);
619 :
620 : /**
621 : * dev_uc_sync - Synchronize device's unicast list to another device
622 : * @to: destination device
623 : * @from: source device
624 : *
625 : * Add newly added addresses to the destination device and release
626 : * addresses that have no users left. The source device must be
627 : * locked by netif_addr_lock_bh.
628 : *
629 : * This function is intended to be called from the dev->set_rx_mode
630 : * function of layered software devices. This function assumes that
631 : * addresses will only ever be synced to the @to devices and no other.
632 : */
633 0 : int dev_uc_sync(struct net_device *to, struct net_device *from)
634 : {
635 0 : int err = 0;
636 :
637 0 : if (to->addr_len != from->addr_len)
638 : return -EINVAL;
639 :
640 0 : netif_addr_lock(to);
641 0 : err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len);
642 0 : if (!err)
643 0 : __dev_set_rx_mode(to);
644 0 : netif_addr_unlock(to);
645 0 : return err;
646 : }
647 : EXPORT_SYMBOL(dev_uc_sync);
648 :
649 : /**
650 : * dev_uc_sync_multiple - Synchronize device's unicast list to another
651 : * device, but allow for multiple calls to sync to multiple devices.
652 : * @to: destination device
653 : * @from: source device
654 : *
655 : * Add newly added addresses to the destination device and release
656 : * addresses that have been deleted from the source. The source device
657 : * must be locked by netif_addr_lock_bh.
658 : *
659 : * This function is intended to be called from the dev->set_rx_mode
660 : * function of layered software devices. It allows for a single source
661 : * device to be synced to multiple destination devices.
662 : */
663 0 : int dev_uc_sync_multiple(struct net_device *to, struct net_device *from)
664 : {
665 0 : int err = 0;
666 :
667 0 : if (to->addr_len != from->addr_len)
668 : return -EINVAL;
669 :
670 0 : netif_addr_lock(to);
671 0 : err = __hw_addr_sync_multiple(&to->uc, &from->uc, to->addr_len);
672 0 : if (!err)
673 0 : __dev_set_rx_mode(to);
674 0 : netif_addr_unlock(to);
675 0 : return err;
676 : }
677 : EXPORT_SYMBOL(dev_uc_sync_multiple);
678 :
679 : /**
680 : * dev_uc_unsync - Remove synchronized addresses from the destination device
681 : * @to: destination device
682 : * @from: source device
683 : *
684 : * Remove all addresses that were added to the destination device by
685 : * dev_uc_sync(). This function is intended to be called from the
686 : * dev->stop function of layered software devices.
687 : */
688 0 : void dev_uc_unsync(struct net_device *to, struct net_device *from)
689 : {
690 0 : if (to->addr_len != from->addr_len)
691 : return;
692 :
693 : /* netif_addr_lock_bh() uses lockdep subclass 0, this is okay for two
694 : * reasons:
695 : * 1) This is always called without any addr_list_lock, so as the
696 : * outermost one here, it must be 0.
697 : * 2) This is called by some callers after unlinking the upper device,
698 : * so the dev->lower_level becomes 1 again.
699 : * Therefore, the subclass for 'from' is 0, for 'to' is either 1 or
700 : * larger.
701 : */
702 0 : netif_addr_lock_bh(from);
703 0 : netif_addr_lock(to);
704 0 : __hw_addr_unsync(&to->uc, &from->uc, to->addr_len);
705 0 : __dev_set_rx_mode(to);
706 0 : netif_addr_unlock(to);
707 0 : netif_addr_unlock_bh(from);
708 : }
709 : EXPORT_SYMBOL(dev_uc_unsync);
710 :
711 : /**
712 : * dev_uc_flush - Flush unicast addresses
713 : * @dev: device
714 : *
715 : * Flush unicast addresses.
716 : */
717 0 : void dev_uc_flush(struct net_device *dev)
718 : {
719 0 : netif_addr_lock_bh(dev);
720 0 : __hw_addr_flush(&dev->uc);
721 0 : netif_addr_unlock_bh(dev);
722 0 : }
723 : EXPORT_SYMBOL(dev_uc_flush);
724 :
725 : /**
726 : * dev_uc_flush - Init unicast address list
727 : * @dev: device
728 : *
729 : * Init unicast address list.
730 : */
731 3 : void dev_uc_init(struct net_device *dev)
732 : {
733 3 : __hw_addr_init(&dev->uc);
734 3 : }
735 : EXPORT_SYMBOL(dev_uc_init);
736 :
737 : /*
738 : * Multicast list handling functions
739 : */
740 :
741 : /**
742 : * dev_mc_add_excl - Add a global secondary multicast address
743 : * @dev: device
744 : * @addr: address to add
745 : */
746 0 : int dev_mc_add_excl(struct net_device *dev, const unsigned char *addr)
747 : {
748 0 : struct netdev_hw_addr *ha;
749 0 : int err;
750 :
751 0 : netif_addr_lock_bh(dev);
752 0 : list_for_each_entry(ha, &dev->mc.list, list) {
753 0 : if (!memcmp(ha->addr, addr, dev->addr_len) &&
754 0 : ha->type == NETDEV_HW_ADDR_T_MULTICAST) {
755 0 : err = -EEXIST;
756 0 : goto out;
757 : }
758 : }
759 0 : err = __hw_addr_create_ex(&dev->mc, addr, dev->addr_len,
760 : NETDEV_HW_ADDR_T_MULTICAST, true, false);
761 0 : if (!err)
762 0 : __dev_set_rx_mode(dev);
763 0 : out:
764 0 : netif_addr_unlock_bh(dev);
765 0 : return err;
766 : }
767 : EXPORT_SYMBOL(dev_mc_add_excl);
768 :
769 1 : static int __dev_mc_add(struct net_device *dev, const unsigned char *addr,
770 : bool global)
771 : {
772 1 : int err;
773 :
774 1 : netif_addr_lock_bh(dev);
775 1 : err = __hw_addr_add_ex(&dev->mc, addr, dev->addr_len,
776 : NETDEV_HW_ADDR_T_MULTICAST, global, false, 0);
777 1 : if (!err)
778 1 : __dev_set_rx_mode(dev);
779 1 : netif_addr_unlock_bh(dev);
780 1 : return err;
781 : }
782 : /**
783 : * dev_mc_add - Add a multicast address
784 : * @dev: device
785 : * @addr: address to add
786 : *
787 : * Add a multicast address to the device or increase
788 : * the reference count if it already exists.
789 : */
790 1 : int dev_mc_add(struct net_device *dev, const unsigned char *addr)
791 : {
792 1 : return __dev_mc_add(dev, addr, false);
793 : }
794 : EXPORT_SYMBOL(dev_mc_add);
795 :
796 : /**
797 : * dev_mc_add_global - Add a global multicast address
798 : * @dev: device
799 : * @addr: address to add
800 : *
801 : * Add a global multicast address to the device.
802 : */
803 0 : int dev_mc_add_global(struct net_device *dev, const unsigned char *addr)
804 : {
805 0 : return __dev_mc_add(dev, addr, true);
806 : }
807 : EXPORT_SYMBOL(dev_mc_add_global);
808 :
809 0 : static int __dev_mc_del(struct net_device *dev, const unsigned char *addr,
810 : bool global)
811 : {
812 0 : int err;
813 :
814 0 : netif_addr_lock_bh(dev);
815 0 : err = __hw_addr_del_ex(&dev->mc, addr, dev->addr_len,
816 : NETDEV_HW_ADDR_T_MULTICAST, global, false);
817 0 : if (!err)
818 0 : __dev_set_rx_mode(dev);
819 0 : netif_addr_unlock_bh(dev);
820 0 : return err;
821 : }
822 :
823 : /**
824 : * dev_mc_del - Delete a multicast address.
825 : * @dev: device
826 : * @addr: address to delete
827 : *
828 : * Release reference to a multicast address and remove it
829 : * from the device if the reference count drops to zero.
830 : */
831 0 : int dev_mc_del(struct net_device *dev, const unsigned char *addr)
832 : {
833 0 : return __dev_mc_del(dev, addr, false);
834 : }
835 : EXPORT_SYMBOL(dev_mc_del);
836 :
837 : /**
838 : * dev_mc_del_global - Delete a global multicast address.
839 : * @dev: device
840 : * @addr: address to delete
841 : *
842 : * Release reference to a multicast address and remove it
843 : * from the device if the reference count drops to zero.
844 : */
845 0 : int dev_mc_del_global(struct net_device *dev, const unsigned char *addr)
846 : {
847 0 : return __dev_mc_del(dev, addr, true);
848 : }
849 : EXPORT_SYMBOL(dev_mc_del_global);
850 :
851 : /**
852 : * dev_mc_sync - Synchronize device's multicast list to another device
853 : * @to: destination device
854 : * @from: source device
855 : *
856 : * Add newly added addresses to the destination device and release
857 : * addresses that have no users left. The source device must be
858 : * locked by netif_addr_lock_bh.
859 : *
860 : * This function is intended to be called from the ndo_set_rx_mode
861 : * function of layered software devices.
862 : */
863 0 : int dev_mc_sync(struct net_device *to, struct net_device *from)
864 : {
865 0 : int err = 0;
866 :
867 0 : if (to->addr_len != from->addr_len)
868 : return -EINVAL;
869 :
870 0 : netif_addr_lock(to);
871 0 : err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len);
872 0 : if (!err)
873 0 : __dev_set_rx_mode(to);
874 0 : netif_addr_unlock(to);
875 0 : return err;
876 : }
877 : EXPORT_SYMBOL(dev_mc_sync);
878 :
879 : /**
880 : * dev_mc_sync_multiple - Synchronize device's multicast list to another
881 : * device, but allow for multiple calls to sync to multiple devices.
882 : * @to: destination device
883 : * @from: source device
884 : *
885 : * Add newly added addresses to the destination device and release
886 : * addresses that have no users left. The source device must be
887 : * locked by netif_addr_lock_bh.
888 : *
889 : * This function is intended to be called from the ndo_set_rx_mode
890 : * function of layered software devices. It allows for a single
891 : * source device to be synced to multiple destination devices.
892 : */
893 0 : int dev_mc_sync_multiple(struct net_device *to, struct net_device *from)
894 : {
895 0 : int err = 0;
896 :
897 0 : if (to->addr_len != from->addr_len)
898 : return -EINVAL;
899 :
900 0 : netif_addr_lock(to);
901 0 : err = __hw_addr_sync_multiple(&to->mc, &from->mc, to->addr_len);
902 0 : if (!err)
903 0 : __dev_set_rx_mode(to);
904 0 : netif_addr_unlock(to);
905 0 : return err;
906 : }
907 : EXPORT_SYMBOL(dev_mc_sync_multiple);
908 :
909 : /**
910 : * dev_mc_unsync - Remove synchronized addresses from the destination device
911 : * @to: destination device
912 : * @from: source device
913 : *
914 : * Remove all addresses that were added to the destination device by
915 : * dev_mc_sync(). This function is intended to be called from the
916 : * dev->stop function of layered software devices.
917 : */
918 0 : void dev_mc_unsync(struct net_device *to, struct net_device *from)
919 : {
920 0 : if (to->addr_len != from->addr_len)
921 : return;
922 :
923 : /* See the above comments inside dev_uc_unsync(). */
924 0 : netif_addr_lock_bh(from);
925 0 : netif_addr_lock(to);
926 0 : __hw_addr_unsync(&to->mc, &from->mc, to->addr_len);
927 0 : __dev_set_rx_mode(to);
928 0 : netif_addr_unlock(to);
929 0 : netif_addr_unlock_bh(from);
930 : }
931 : EXPORT_SYMBOL(dev_mc_unsync);
932 :
933 : /**
934 : * dev_mc_flush - Flush multicast addresses
935 : * @dev: device
936 : *
937 : * Flush multicast addresses.
938 : */
939 0 : void dev_mc_flush(struct net_device *dev)
940 : {
941 0 : netif_addr_lock_bh(dev);
942 0 : __hw_addr_flush(&dev->mc);
943 0 : netif_addr_unlock_bh(dev);
944 0 : }
945 : EXPORT_SYMBOL(dev_mc_flush);
946 :
947 : /**
948 : * dev_mc_init - Init multicast address list
949 : * @dev: device
950 : *
951 : * Init multicast address list.
952 : */
953 3 : void dev_mc_init(struct net_device *dev)
954 : {
955 3 : __hw_addr_init(&dev->mc);
956 3 : }
957 : EXPORT_SYMBOL(dev_mc_init);
|