root/net/core/dev_addr_lists.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. __hw_addr_create_ex
  2. __hw_addr_add_ex
  3. __hw_addr_add
  4. __hw_addr_del_entry
  5. __hw_addr_del_ex
  6. __hw_addr_del
  7. __hw_addr_sync_one
  8. __hw_addr_unsync_one
  9. __hw_addr_sync_multiple
  10. __hw_addr_sync
  11. __hw_addr_unsync
  12. __hw_addr_sync_dev
  13. __hw_addr_ref_sync_dev
  14. __hw_addr_ref_unsync_dev
  15. __hw_addr_unsync_dev
  16. __hw_addr_flush
  17. __hw_addr_init
  18. dev_addr_flush
  19. dev_addr_init
  20. dev_addr_add
  21. dev_addr_del
  22. dev_uc_add_excl
  23. dev_uc_add
  24. dev_uc_del
  25. dev_uc_sync
  26. dev_uc_sync_multiple
  27. dev_uc_unsync
  28. dev_uc_flush
  29. dev_uc_init
  30. dev_mc_add_excl
  31. __dev_mc_add
  32. dev_mc_add
  33. dev_mc_add_global
  34. __dev_mc_del
  35. dev_mc_del
  36. dev_mc_del_global
  37. dev_mc_sync
  38. dev_mc_sync_multiple
  39. dev_mc_unsync
  40. dev_mc_flush
  41. dev_mc_init

   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 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         struct netdev_hw_addr *ha;
  25         int alloc_size;
  26 
  27         alloc_size = sizeof(*ha);
  28         if (alloc_size < L1_CACHE_BYTES)
  29                 alloc_size = L1_CACHE_BYTES;
  30         ha = kmalloc(alloc_size, GFP_ATOMIC);
  31         if (!ha)
  32                 return -ENOMEM;
  33         memcpy(ha->addr, addr, addr_len);
  34         ha->type = addr_type;
  35         ha->refcount = 1;
  36         ha->global_use = global;
  37         ha->synced = sync ? 1 : 0;
  38         ha->sync_cnt = 0;
  39         list_add_tail_rcu(&ha->list, &list->list);
  40         list->count++;
  41 
  42         return 0;
  43 }
  44 
  45 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         struct netdev_hw_addr *ha;
  51 
  52         if (addr_len > MAX_ADDR_LEN)
  53                 return -EINVAL;
  54 
  55         list_for_each_entry(ha, &list->list, list) {
  56                 if (ha->type == addr_type &&
  57                     !memcmp(ha->addr, addr, addr_len)) {
  58                         if (global) {
  59                                 /* check if addr is already used as global */
  60                                 if (ha->global_use)
  61                                         return 0;
  62                                 else
  63                                         ha->global_use = true;
  64                         }
  65                         if (sync) {
  66                                 if (ha->synced && sync_count)
  67                                         return -EEXIST;
  68                                 else
  69                                         ha->synced++;
  70                         }
  71                         ha->refcount++;
  72                         return 0;
  73                 }
  74         }
  75 
  76         return __hw_addr_create_ex(list, addr, addr_len, addr_type, global,
  77                                    sync);
  78 }
  79 
  80 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         return __hw_addr_add_ex(list, addr, addr_len, addr_type, false, false,
  85                                 0);
  86 }
  87 
  88 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         if (global && !ha->global_use)
  93                 return -ENOENT;
  94 
  95         if (sync && !ha->synced)
  96                 return -ENOENT;
  97 
  98         if (global)
  99                 ha->global_use = false;
 100 
 101         if (sync)
 102                 ha->synced--;
 103 
 104         if (--ha->refcount)
 105                 return 0;
 106         list_del_rcu(&ha->list);
 107         kfree_rcu(ha, rcu_head);
 108         list->count--;
 109         return 0;
 110 }
 111 
 112 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         struct netdev_hw_addr *ha;
 117 
 118         list_for_each_entry(ha, &list->list, list) {
 119                 if (!memcmp(ha->addr, addr, addr_len) &&
 120                     (ha->type == addr_type || !addr_type))
 121                         return __hw_addr_del_entry(list, ha, global, sync);
 122         }
 123         return -ENOENT;
 124 }
 125 
 126 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         return __hw_addr_del_ex(list, addr, addr_len, addr_type, false, false);
 131 }
 132 
 133 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         int err;
 138 
 139         err = __hw_addr_add_ex(to_list, ha->addr, addr_len, ha->type,
 140                                false, true, ha->sync_cnt);
 141         if (err && err != -EEXIST)
 142                 return err;
 143 
 144         if (!err) {
 145                 ha->sync_cnt++;
 146                 ha->refcount++;
 147         }
 148 
 149         return 0;
 150 }
 151 
 152 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         int err;
 158 
 159         err = __hw_addr_del_ex(to_list, ha->addr, addr_len, ha->type,
 160                                false, true);
 161         if (err)
 162                 return;
 163         ha->sync_cnt--;
 164         /* address on from list is not marked synced */
 165         __hw_addr_del_entry(from_list, ha, false, false);
 166 }
 167 
 168 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         int err = 0;
 173         struct netdev_hw_addr *ha, *tmp;
 174 
 175         list_for_each_entry_safe(ha, tmp, &from_list->list, list) {
 176                 if (ha->sync_cnt == ha->refcount) {
 177                         __hw_addr_unsync_one(to_list, from_list, ha, addr_len);
 178                 } else {
 179                         err = __hw_addr_sync_one(to_list, ha, addr_len);
 180                         if (err)
 181                                 break;
 182                 }
 183         }
 184         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 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         int err = 0;
 197         struct netdev_hw_addr *ha, *tmp;
 198 
 199         list_for_each_entry_safe(ha, tmp, &from_list->list, list) {
 200                 if (!ha->sync_cnt) {
 201                         err = __hw_addr_sync_one(to_list, ha, addr_len);
 202                         if (err)
 203                                 break;
 204                 } else if (ha->refcount == 1)
 205                         __hw_addr_unsync_one(to_list, from_list, ha, addr_len);
 206         }
 207         return err;
 208 }
 209 EXPORT_SYMBOL(__hw_addr_sync);
 210 
 211 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         struct netdev_hw_addr *ha, *tmp;
 216 
 217         list_for_each_entry_safe(ha, tmp, &from_list->list, list) {
 218                 if (ha->sync_cnt)
 219                         __hw_addr_unsync_one(to_list, from_list, ha, addr_len);
 220         }
 221 }
 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 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         struct netdev_hw_addr *ha, *tmp;
 244         int err;
 245 
 246         /* first go through and flush out any stale entries */
 247         list_for_each_entry_safe(ha, tmp, &list->list, list) {
 248                 if (!ha->sync_cnt || ha->refcount != 1)
 249                         continue;
 250 
 251                 /* if unsync is defined and fails defer unsyncing address */
 252                 if (unsync && unsync(dev, ha->addr))
 253                         continue;
 254 
 255                 ha->sync_cnt--;
 256                 __hw_addr_del_entry(list, ha, false, false);
 257         }
 258 
 259         /* go through and sync new entries to the list */
 260         list_for_each_entry_safe(ha, tmp, &list->list, list) {
 261                 if (ha->sync_cnt)
 262                         continue;
 263 
 264                 err = sync(dev, ha->addr);
 265                 if (err)
 266                         return err;
 267 
 268                 ha->sync_cnt++;
 269                 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 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         struct netdev_hw_addr *ha, *tmp;
 300         int err, ref_cnt;
 301 
 302         /* first go through and flush out any unsynced/stale entries */
 303         list_for_each_entry_safe(ha, tmp, &list->list, list) {
 304                 /* sync if address is not used */
 305                 if ((ha->sync_cnt << 1) <= ha->refcount)
 306                         continue;
 307 
 308                 /* if fails defer unsyncing address */
 309                 ref_cnt = ha->refcount - ha->sync_cnt;
 310                 if (unsync && unsync(dev, ha->addr, ref_cnt))
 311                         continue;
 312 
 313                 ha->refcount = (ref_cnt << 1) + 1;
 314                 ha->sync_cnt = ref_cnt;
 315                 __hw_addr_del_entry(list, ha, false, false);
 316         }
 317 
 318         /* go through and sync updated/new entries to the list */
 319         list_for_each_entry_safe(ha, tmp, &list->list, list) {
 320                 /* sync if address added or reused */
 321                 if ((ha->sync_cnt << 1) >= ha->refcount)
 322                         continue;
 323 
 324                 ref_cnt = ha->refcount - ha->sync_cnt;
 325                 err = sync(dev, ha->addr, ref_cnt);
 326                 if (err)
 327                         return err;
 328 
 329                 ha->refcount = ref_cnt << 1;
 330                 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 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         struct netdev_hw_addr *ha, *tmp;
 357 
 358         list_for_each_entry_safe(ha, tmp, &list->list, list) {
 359                 if (!ha->sync_cnt)
 360                         continue;
 361 
 362                 /* if fails defer unsyncing address */
 363                 if (unsync && unsync(dev, ha->addr, ha->sync_cnt))
 364                         continue;
 365 
 366                 ha->refcount -= ha->sync_cnt - 1;
 367                 ha->sync_cnt = 0;
 368                 __hw_addr_del_entry(list, ha, false, false);
 369         }
 370 }
 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 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         struct netdev_hw_addr *ha, *tmp;
 391 
 392         list_for_each_entry_safe(ha, tmp, &list->list, list) {
 393                 if (!ha->sync_cnt)
 394                         continue;
 395 
 396                 /* if unsync is defined and fails defer unsyncing address */
 397                 if (unsync && unsync(dev, ha->addr))
 398                         continue;
 399 
 400                 ha->sync_cnt--;
 401                 __hw_addr_del_entry(list, ha, false, false);
 402         }
 403 }
 404 EXPORT_SYMBOL(__hw_addr_unsync_dev);
 405 
 406 static void __hw_addr_flush(struct netdev_hw_addr_list *list)
 407 {
 408         struct netdev_hw_addr *ha, *tmp;
 409 
 410         list_for_each_entry_safe(ha, tmp, &list->list, list) {
 411                 list_del_rcu(&ha->list);
 412                 kfree_rcu(ha, rcu_head);
 413         }
 414         list->count = 0;
 415 }
 416 
 417 void __hw_addr_init(struct netdev_hw_addr_list *list)
 418 {
 419         INIT_LIST_HEAD(&list->list);
 420         list->count = 0;
 421 }
 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 void dev_addr_flush(struct net_device *dev)
 437 {
 438         /* rtnl_mutex must be held here */
 439 
 440         __hw_addr_flush(&dev->dev_addrs);
 441         dev->dev_addr = NULL;
 442 }
 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 int dev_addr_init(struct net_device *dev)
 455 {
 456         unsigned char addr[MAX_ADDR_LEN];
 457         struct netdev_hw_addr *ha;
 458         int err;
 459 
 460         /* rtnl_mutex must be held here */
 461 
 462         __hw_addr_init(&dev->dev_addrs);
 463         memset(addr, 0, sizeof(addr));
 464         err = __hw_addr_add(&dev->dev_addrs, addr, sizeof(addr),
 465                             NETDEV_HW_ADDR_T_LAN);
 466         if (!err) {
 467                 /*
 468                  * Get the first (previously created) address from the list
 469                  * and set dev_addr pointer to this location.
 470                  */
 471                 ha = list_first_entry(&dev->dev_addrs.list,
 472                                       struct netdev_hw_addr, list);
 473                 dev->dev_addr = ha->addr;
 474         }
 475         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 int dev_addr_add(struct net_device *dev, const unsigned char *addr,
 491                  unsigned char addr_type)
 492 {
 493         int err;
 494 
 495         ASSERT_RTNL();
 496 
 497         err = dev_pre_changeaddr_notify(dev, addr, NULL);
 498         if (err)
 499                 return err;
 500         err = __hw_addr_add(&dev->dev_addrs, addr, dev->addr_len, addr_type);
 501         if (!err)
 502                 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 int dev_addr_del(struct net_device *dev, const unsigned char *addr,
 519                  unsigned char addr_type)
 520 {
 521         int err;
 522         struct netdev_hw_addr *ha;
 523 
 524         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         ha = list_first_entry(&dev->dev_addrs.list,
 531                               struct netdev_hw_addr, list);
 532         if (!memcmp(ha->addr, addr, dev->addr_len) &&
 533             ha->type == addr_type && ha->refcount == 1)
 534                 return -ENOENT;
 535 
 536         err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len,
 537                             addr_type);
 538         if (!err)
 539                 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 int dev_uc_add_excl(struct net_device *dev, const unsigned char *addr)
 554 {
 555         struct netdev_hw_addr *ha;
 556         int err;
 557 
 558         netif_addr_lock_bh(dev);
 559         list_for_each_entry(ha, &dev->uc.list, list) {
 560                 if (!memcmp(ha->addr, addr, dev->addr_len) &&
 561                     ha->type == NETDEV_HW_ADDR_T_UNICAST) {
 562                         err = -EEXIST;
 563                         goto out;
 564                 }
 565         }
 566         err = __hw_addr_create_ex(&dev->uc, addr, dev->addr_len,
 567                                   NETDEV_HW_ADDR_T_UNICAST, true, false);
 568         if (!err)
 569                 __dev_set_rx_mode(dev);
 570 out:
 571         netif_addr_unlock_bh(dev);
 572         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 int dev_uc_add(struct net_device *dev, const unsigned char *addr)
 585 {
 586         int err;
 587 
 588         netif_addr_lock_bh(dev);
 589         err = __hw_addr_add(&dev->uc, addr, dev->addr_len,
 590                             NETDEV_HW_ADDR_T_UNICAST);
 591         if (!err)
 592                 __dev_set_rx_mode(dev);
 593         netif_addr_unlock_bh(dev);
 594         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 int dev_uc_del(struct net_device *dev, const unsigned char *addr)
 607 {
 608         int err;
 609 
 610         netif_addr_lock_bh(dev);
 611         err = __hw_addr_del(&dev->uc, addr, dev->addr_len,
 612                             NETDEV_HW_ADDR_T_UNICAST);
 613         if (!err)
 614                 __dev_set_rx_mode(dev);
 615         netif_addr_unlock_bh(dev);
 616         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 int dev_uc_sync(struct net_device *to, struct net_device *from)
 634 {
 635         int err = 0;
 636 
 637         if (to->addr_len != from->addr_len)
 638                 return -EINVAL;
 639 
 640         netif_addr_lock(to);
 641         err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len);
 642         if (!err)
 643                 __dev_set_rx_mode(to);
 644         netif_addr_unlock(to);
 645         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 int dev_uc_sync_multiple(struct net_device *to, struct net_device *from)
 664 {
 665         int err = 0;
 666 
 667         if (to->addr_len != from->addr_len)
 668                 return -EINVAL;
 669 
 670         netif_addr_lock(to);
 671         err = __hw_addr_sync_multiple(&to->uc, &from->uc, to->addr_len);
 672         if (!err)
 673                 __dev_set_rx_mode(to);
 674         netif_addr_unlock(to);
 675         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 void dev_uc_unsync(struct net_device *to, struct net_device *from)
 689 {
 690         if (to->addr_len != from->addr_len)
 691                 return;
 692 
 693         netif_addr_lock_bh(from);
 694         netif_addr_lock(to);
 695         __hw_addr_unsync(&to->uc, &from->uc, to->addr_len);
 696         __dev_set_rx_mode(to);
 697         netif_addr_unlock(to);
 698         netif_addr_unlock_bh(from);
 699 }
 700 EXPORT_SYMBOL(dev_uc_unsync);
 701 
 702 /**
 703  *      dev_uc_flush - Flush unicast addresses
 704  *      @dev: device
 705  *
 706  *      Flush unicast addresses.
 707  */
 708 void dev_uc_flush(struct net_device *dev)
 709 {
 710         netif_addr_lock_bh(dev);
 711         __hw_addr_flush(&dev->uc);
 712         netif_addr_unlock_bh(dev);
 713 }
 714 EXPORT_SYMBOL(dev_uc_flush);
 715 
 716 /**
 717  *      dev_uc_flush - Init unicast address list
 718  *      @dev: device
 719  *
 720  *      Init unicast address list.
 721  */
 722 void dev_uc_init(struct net_device *dev)
 723 {
 724         __hw_addr_init(&dev->uc);
 725 }
 726 EXPORT_SYMBOL(dev_uc_init);
 727 
 728 /*
 729  * Multicast list handling functions
 730  */
 731 
 732 /**
 733  *      dev_mc_add_excl - Add a global secondary multicast address
 734  *      @dev: device
 735  *      @addr: address to add
 736  */
 737 int dev_mc_add_excl(struct net_device *dev, const unsigned char *addr)
 738 {
 739         struct netdev_hw_addr *ha;
 740         int err;
 741 
 742         netif_addr_lock_bh(dev);
 743         list_for_each_entry(ha, &dev->mc.list, list) {
 744                 if (!memcmp(ha->addr, addr, dev->addr_len) &&
 745                     ha->type == NETDEV_HW_ADDR_T_MULTICAST) {
 746                         err = -EEXIST;
 747                         goto out;
 748                 }
 749         }
 750         err = __hw_addr_create_ex(&dev->mc, addr, dev->addr_len,
 751                                   NETDEV_HW_ADDR_T_MULTICAST, true, false);
 752         if (!err)
 753                 __dev_set_rx_mode(dev);
 754 out:
 755         netif_addr_unlock_bh(dev);
 756         return err;
 757 }
 758 EXPORT_SYMBOL(dev_mc_add_excl);
 759 
 760 static int __dev_mc_add(struct net_device *dev, const unsigned char *addr,
 761                         bool global)
 762 {
 763         int err;
 764 
 765         netif_addr_lock_bh(dev);
 766         err = __hw_addr_add_ex(&dev->mc, addr, dev->addr_len,
 767                                NETDEV_HW_ADDR_T_MULTICAST, global, false, 0);
 768         if (!err)
 769                 __dev_set_rx_mode(dev);
 770         netif_addr_unlock_bh(dev);
 771         return err;
 772 }
 773 /**
 774  *      dev_mc_add - Add a multicast address
 775  *      @dev: device
 776  *      @addr: address to add
 777  *
 778  *      Add a multicast address to the device or increase
 779  *      the reference count if it already exists.
 780  */
 781 int dev_mc_add(struct net_device *dev, const unsigned char *addr)
 782 {
 783         return __dev_mc_add(dev, addr, false);
 784 }
 785 EXPORT_SYMBOL(dev_mc_add);
 786 
 787 /**
 788  *      dev_mc_add_global - Add a global multicast address
 789  *      @dev: device
 790  *      @addr: address to add
 791  *
 792  *      Add a global multicast address to the device.
 793  */
 794 int dev_mc_add_global(struct net_device *dev, const unsigned char *addr)
 795 {
 796         return __dev_mc_add(dev, addr, true);
 797 }
 798 EXPORT_SYMBOL(dev_mc_add_global);
 799 
 800 static int __dev_mc_del(struct net_device *dev, const unsigned char *addr,
 801                         bool global)
 802 {
 803         int err;
 804 
 805         netif_addr_lock_bh(dev);
 806         err = __hw_addr_del_ex(&dev->mc, addr, dev->addr_len,
 807                                NETDEV_HW_ADDR_T_MULTICAST, global, false);
 808         if (!err)
 809                 __dev_set_rx_mode(dev);
 810         netif_addr_unlock_bh(dev);
 811         return err;
 812 }
 813 
 814 /**
 815  *      dev_mc_del - Delete a multicast address.
 816  *      @dev: device
 817  *      @addr: address to delete
 818  *
 819  *      Release reference to a multicast address and remove it
 820  *      from the device if the reference count drops to zero.
 821  */
 822 int dev_mc_del(struct net_device *dev, const unsigned char *addr)
 823 {
 824         return __dev_mc_del(dev, addr, false);
 825 }
 826 EXPORT_SYMBOL(dev_mc_del);
 827 
 828 /**
 829  *      dev_mc_del_global - Delete a global multicast address.
 830  *      @dev: device
 831  *      @addr: address to delete
 832  *
 833  *      Release reference to a multicast address and remove it
 834  *      from the device if the reference count drops to zero.
 835  */
 836 int dev_mc_del_global(struct net_device *dev, const unsigned char *addr)
 837 {
 838         return __dev_mc_del(dev, addr, true);
 839 }
 840 EXPORT_SYMBOL(dev_mc_del_global);
 841 
 842 /**
 843  *      dev_mc_sync - Synchronize device's multicast list to another device
 844  *      @to: destination device
 845  *      @from: source device
 846  *
 847  *      Add newly added addresses to the destination device and release
 848  *      addresses that have no users left. The source device must be
 849  *      locked by netif_addr_lock_bh.
 850  *
 851  *      This function is intended to be called from the ndo_set_rx_mode
 852  *      function of layered software devices.
 853  */
 854 int dev_mc_sync(struct net_device *to, struct net_device *from)
 855 {
 856         int err = 0;
 857 
 858         if (to->addr_len != from->addr_len)
 859                 return -EINVAL;
 860 
 861         netif_addr_lock(to);
 862         err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len);
 863         if (!err)
 864                 __dev_set_rx_mode(to);
 865         netif_addr_unlock(to);
 866         return err;
 867 }
 868 EXPORT_SYMBOL(dev_mc_sync);
 869 
 870 /**
 871  *      dev_mc_sync_multiple - Synchronize device's multicast list to another
 872  *      device, but allow for multiple calls to sync to multiple devices.
 873  *      @to: destination device
 874  *      @from: source device
 875  *
 876  *      Add newly added addresses to the destination device and release
 877  *      addresses that have no users left. The source device must be
 878  *      locked by netif_addr_lock_bh.
 879  *
 880  *      This function is intended to be called from the ndo_set_rx_mode
 881  *      function of layered software devices.  It allows for a single
 882  *      source device to be synced to multiple destination devices.
 883  */
 884 int dev_mc_sync_multiple(struct net_device *to, struct net_device *from)
 885 {
 886         int err = 0;
 887 
 888         if (to->addr_len != from->addr_len)
 889                 return -EINVAL;
 890 
 891         netif_addr_lock(to);
 892         err = __hw_addr_sync_multiple(&to->mc, &from->mc, to->addr_len);
 893         if (!err)
 894                 __dev_set_rx_mode(to);
 895         netif_addr_unlock(to);
 896         return err;
 897 }
 898 EXPORT_SYMBOL(dev_mc_sync_multiple);
 899 
 900 /**
 901  *      dev_mc_unsync - Remove synchronized addresses from the destination device
 902  *      @to: destination device
 903  *      @from: source device
 904  *
 905  *      Remove all addresses that were added to the destination device by
 906  *      dev_mc_sync(). This function is intended to be called from the
 907  *      dev->stop function of layered software devices.
 908  */
 909 void dev_mc_unsync(struct net_device *to, struct net_device *from)
 910 {
 911         if (to->addr_len != from->addr_len)
 912                 return;
 913 
 914         netif_addr_lock_bh(from);
 915         netif_addr_lock(to);
 916         __hw_addr_unsync(&to->mc, &from->mc, to->addr_len);
 917         __dev_set_rx_mode(to);
 918         netif_addr_unlock(to);
 919         netif_addr_unlock_bh(from);
 920 }
 921 EXPORT_SYMBOL(dev_mc_unsync);
 922 
 923 /**
 924  *      dev_mc_flush - Flush multicast addresses
 925  *      @dev: device
 926  *
 927  *      Flush multicast addresses.
 928  */
 929 void dev_mc_flush(struct net_device *dev)
 930 {
 931         netif_addr_lock_bh(dev);
 932         __hw_addr_flush(&dev->mc);
 933         netif_addr_unlock_bh(dev);
 934 }
 935 EXPORT_SYMBOL(dev_mc_flush);
 936 
 937 /**
 938  *      dev_mc_init - Init multicast address list
 939  *      @dev: device
 940  *
 941  *      Init multicast address list.
 942  */
 943 void dev_mc_init(struct net_device *dev)
 944 {
 945         __hw_addr_init(&dev->mc);
 946 }
 947 EXPORT_SYMBOL(dev_mc_init);

/* [<][>][^][v][top][bottom][index][help] */