diff options
author | Jiri Pirko <jpirko@redhat.com> | 2009-06-16 21:12:19 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-18 03:29:08 -0400 |
commit | 31278e71471399beaff9280737e52b47db4dc345 (patch) | |
tree | 25fe2ff8e48a75b7f569dccc463f3bd2561c6c66 /net | |
parent | 7b85576d15bf2574b0a451108f59f9ad4170dd3f (diff) |
net: group address list and its count
This patch is inspired by patch recently posted by Johannes Berg. Basically what
my patch does is to group list and a count of addresses into newly introduced
structure netdev_hw_addr_list. This brings us two benefits:
1) struct net_device becames a bit nicer.
2) in the future there will be a possibility to operate with lists independently
on netdevices (with exporting right functions).
I wanted to introduce this patch before I'll post a multicast lists conversion.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
drivers/net/bnx2.c | 4 +-
drivers/net/e1000/e1000_main.c | 4 +-
drivers/net/ixgbe/ixgbe_main.c | 6 +-
drivers/net/mv643xx_eth.c | 2 +-
drivers/net/niu.c | 4 +-
drivers/net/virtio_net.c | 10 ++--
drivers/s390/net/qeth_l2_main.c | 2 +-
include/linux/netdevice.h | 17 +++--
net/core/dev.c | 130 ++++++++++++++++++--------------------
9 files changed, 89 insertions(+), 90 deletions(-)
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 130 |
1 files changed, 62 insertions, 68 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 576a61574a93..baf2dc13a34a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3461,10 +3461,10 @@ void __dev_set_rx_mode(struct net_device *dev) | |||
3461 | /* Unicast addresses changes may only happen under the rtnl, | 3461 | /* Unicast addresses changes may only happen under the rtnl, |
3462 | * therefore calling __dev_set_promiscuity here is safe. | 3462 | * therefore calling __dev_set_promiscuity here is safe. |
3463 | */ | 3463 | */ |
3464 | if (dev->uc_count > 0 && !dev->uc_promisc) { | 3464 | if (dev->uc.count > 0 && !dev->uc_promisc) { |
3465 | __dev_set_promiscuity(dev, 1); | 3465 | __dev_set_promiscuity(dev, 1); |
3466 | dev->uc_promisc = 1; | 3466 | dev->uc_promisc = 1; |
3467 | } else if (dev->uc_count == 0 && dev->uc_promisc) { | 3467 | } else if (dev->uc.count == 0 && dev->uc_promisc) { |
3468 | __dev_set_promiscuity(dev, -1); | 3468 | __dev_set_promiscuity(dev, -1); |
3469 | dev->uc_promisc = 0; | 3469 | dev->uc_promisc = 0; |
3470 | } | 3470 | } |
@@ -3483,9 +3483,8 @@ void dev_set_rx_mode(struct net_device *dev) | |||
3483 | 3483 | ||
3484 | /* hw addresses list handling functions */ | 3484 | /* hw addresses list handling functions */ |
3485 | 3485 | ||
3486 | static int __hw_addr_add(struct list_head *list, int *delta, | 3486 | static int __hw_addr_add(struct netdev_hw_addr_list *list, unsigned char *addr, |
3487 | unsigned char *addr, int addr_len, | 3487 | int addr_len, unsigned char addr_type) |
3488 | unsigned char addr_type) | ||
3489 | { | 3488 | { |
3490 | struct netdev_hw_addr *ha; | 3489 | struct netdev_hw_addr *ha; |
3491 | int alloc_size; | 3490 | int alloc_size; |
@@ -3493,7 +3492,7 @@ static int __hw_addr_add(struct list_head *list, int *delta, | |||
3493 | if (addr_len > MAX_ADDR_LEN) | 3492 | if (addr_len > MAX_ADDR_LEN) |
3494 | return -EINVAL; | 3493 | return -EINVAL; |
3495 | 3494 | ||
3496 | list_for_each_entry(ha, list, list) { | 3495 | list_for_each_entry(ha, &list->list, list) { |
3497 | if (!memcmp(ha->addr, addr, addr_len) && | 3496 | if (!memcmp(ha->addr, addr, addr_len) && |
3498 | ha->type == addr_type) { | 3497 | ha->type == addr_type) { |
3499 | ha->refcount++; | 3498 | ha->refcount++; |
@@ -3512,9 +3511,8 @@ static int __hw_addr_add(struct list_head *list, int *delta, | |||
3512 | ha->type = addr_type; | 3511 | ha->type = addr_type; |
3513 | ha->refcount = 1; | 3512 | ha->refcount = 1; |
3514 | ha->synced = false; | 3513 | ha->synced = false; |
3515 | list_add_tail_rcu(&ha->list, list); | 3514 | list_add_tail_rcu(&ha->list, &list->list); |
3516 | if (delta) | 3515 | list->count++; |
3517 | (*delta)++; | ||
3518 | return 0; | 3516 | return 0; |
3519 | } | 3517 | } |
3520 | 3518 | ||
@@ -3526,120 +3524,121 @@ static void ha_rcu_free(struct rcu_head *head) | |||
3526 | kfree(ha); | 3524 | kfree(ha); |
3527 | } | 3525 | } |
3528 | 3526 | ||
3529 | static int __hw_addr_del(struct list_head *list, int *delta, | 3527 | static int __hw_addr_del(struct netdev_hw_addr_list *list, unsigned char *addr, |
3530 | unsigned char *addr, int addr_len, | 3528 | int addr_len, unsigned char addr_type) |
3531 | unsigned char addr_type) | ||
3532 | { | 3529 | { |
3533 | struct netdev_hw_addr *ha; | 3530 | struct netdev_hw_addr *ha; |
3534 | 3531 | ||
3535 | list_for_each_entry(ha, list, list) { | 3532 | list_for_each_entry(ha, &list->list, list) { |
3536 | if (!memcmp(ha->addr, addr, addr_len) && | 3533 | if (!memcmp(ha->addr, addr, addr_len) && |
3537 | (ha->type == addr_type || !addr_type)) { | 3534 | (ha->type == addr_type || !addr_type)) { |
3538 | if (--ha->refcount) | 3535 | if (--ha->refcount) |
3539 | return 0; | 3536 | return 0; |
3540 | list_del_rcu(&ha->list); | 3537 | list_del_rcu(&ha->list); |
3541 | call_rcu(&ha->rcu_head, ha_rcu_free); | 3538 | call_rcu(&ha->rcu_head, ha_rcu_free); |
3542 | if (delta) | 3539 | list->count--; |
3543 | (*delta)--; | ||
3544 | return 0; | 3540 | return 0; |
3545 | } | 3541 | } |
3546 | } | 3542 | } |
3547 | return -ENOENT; | 3543 | return -ENOENT; |
3548 | } | 3544 | } |
3549 | 3545 | ||
3550 | static int __hw_addr_add_multiple(struct list_head *to_list, int *to_delta, | 3546 | static int __hw_addr_add_multiple(struct netdev_hw_addr_list *to_list, |
3551 | struct list_head *from_list, int addr_len, | 3547 | struct netdev_hw_addr_list *from_list, |
3548 | int addr_len, | ||
3552 | unsigned char addr_type) | 3549 | unsigned char addr_type) |
3553 | { | 3550 | { |
3554 | int err; | 3551 | int err; |
3555 | struct netdev_hw_addr *ha, *ha2; | 3552 | struct netdev_hw_addr *ha, *ha2; |
3556 | unsigned char type; | 3553 | unsigned char type; |
3557 | 3554 | ||
3558 | list_for_each_entry(ha, from_list, list) { | 3555 | list_for_each_entry(ha, &from_list->list, list) { |
3559 | type = addr_type ? addr_type : ha->type; | 3556 | type = addr_type ? addr_type : ha->type; |
3560 | err = __hw_addr_add(to_list, to_delta, ha->addr, | 3557 | err = __hw_addr_add(to_list, ha->addr, addr_len, type); |
3561 | addr_len, type); | ||
3562 | if (err) | 3558 | if (err) |
3563 | goto unroll; | 3559 | goto unroll; |
3564 | } | 3560 | } |
3565 | return 0; | 3561 | return 0; |
3566 | 3562 | ||
3567 | unroll: | 3563 | unroll: |
3568 | list_for_each_entry(ha2, from_list, list) { | 3564 | list_for_each_entry(ha2, &from_list->list, list) { |
3569 | if (ha2 == ha) | 3565 | if (ha2 == ha) |
3570 | break; | 3566 | break; |
3571 | type = addr_type ? addr_type : ha2->type; | 3567 | type = addr_type ? addr_type : ha2->type; |
3572 | __hw_addr_del(to_list, to_delta, ha2->addr, | 3568 | __hw_addr_del(to_list, ha2->addr, addr_len, type); |
3573 | addr_len, type); | ||
3574 | } | 3569 | } |
3575 | return err; | 3570 | return err; |
3576 | } | 3571 | } |
3577 | 3572 | ||
3578 | static void __hw_addr_del_multiple(struct list_head *to_list, int *to_delta, | 3573 | static void __hw_addr_del_multiple(struct netdev_hw_addr_list *to_list, |
3579 | struct list_head *from_list, int addr_len, | 3574 | struct netdev_hw_addr_list *from_list, |
3575 | int addr_len, | ||
3580 | unsigned char addr_type) | 3576 | unsigned char addr_type) |
3581 | { | 3577 | { |
3582 | struct netdev_hw_addr *ha; | 3578 | struct netdev_hw_addr *ha; |
3583 | unsigned char type; | 3579 | unsigned char type; |
3584 | 3580 | ||
3585 | list_for_each_entry(ha, from_list, list) { | 3581 | list_for_each_entry(ha, &from_list->list, list) { |
3586 | type = addr_type ? addr_type : ha->type; | 3582 | type = addr_type ? addr_type : ha->type; |
3587 | __hw_addr_del(to_list, to_delta, ha->addr, | 3583 | __hw_addr_del(to_list, ha->addr, addr_len, addr_type); |
3588 | addr_len, addr_type); | ||
3589 | } | 3584 | } |
3590 | } | 3585 | } |
3591 | 3586 | ||
3592 | static int __hw_addr_sync(struct list_head *to_list, int *to_delta, | 3587 | static int __hw_addr_sync(struct netdev_hw_addr_list *to_list, |
3593 | struct list_head *from_list, int *from_delta, | 3588 | struct netdev_hw_addr_list *from_list, |
3594 | int addr_len) | 3589 | int addr_len) |
3595 | { | 3590 | { |
3596 | int err = 0; | 3591 | int err = 0; |
3597 | struct netdev_hw_addr *ha, *tmp; | 3592 | struct netdev_hw_addr *ha, *tmp; |
3598 | 3593 | ||
3599 | list_for_each_entry_safe(ha, tmp, from_list, list) { | 3594 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { |
3600 | if (!ha->synced) { | 3595 | if (!ha->synced) { |
3601 | err = __hw_addr_add(to_list, to_delta, ha->addr, | 3596 | err = __hw_addr_add(to_list, ha->addr, |
3602 | addr_len, ha->type); | 3597 | addr_len, ha->type); |
3603 | if (err) | 3598 | if (err) |
3604 | break; | 3599 | break; |
3605 | ha->synced = true; | 3600 | ha->synced = true; |
3606 | ha->refcount++; | 3601 | ha->refcount++; |
3607 | } else if (ha->refcount == 1) { | 3602 | } else if (ha->refcount == 1) { |
3608 | __hw_addr_del(to_list, to_delta, ha->addr, | 3603 | __hw_addr_del(to_list, ha->addr, addr_len, ha->type); |
3609 | addr_len, ha->type); | 3604 | __hw_addr_del(from_list, ha->addr, addr_len, ha->type); |
3610 | __hw_addr_del(from_list, from_delta, ha->addr, | ||
3611 | addr_len, ha->type); | ||
3612 | } | 3605 | } |
3613 | } | 3606 | } |
3614 | return err; | 3607 | return err; |
3615 | } | 3608 | } |
3616 | 3609 | ||
3617 | static void __hw_addr_unsync(struct list_head *to_list, int *to_delta, | 3610 | static void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, |
3618 | struct list_head *from_list, int *from_delta, | 3611 | struct netdev_hw_addr_list *from_list, |
3619 | int addr_len) | 3612 | int addr_len) |
3620 | { | 3613 | { |
3621 | struct netdev_hw_addr *ha, *tmp; | 3614 | struct netdev_hw_addr *ha, *tmp; |
3622 | 3615 | ||
3623 | list_for_each_entry_safe(ha, tmp, from_list, list) { | 3616 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { |
3624 | if (ha->synced) { | 3617 | if (ha->synced) { |
3625 | __hw_addr_del(to_list, to_delta, ha->addr, | 3618 | __hw_addr_del(to_list, ha->addr, |
3626 | addr_len, ha->type); | 3619 | addr_len, ha->type); |
3627 | ha->synced = false; | 3620 | ha->synced = false; |
3628 | __hw_addr_del(from_list, from_delta, ha->addr, | 3621 | __hw_addr_del(from_list, ha->addr, |
3629 | addr_len, ha->type); | 3622 | addr_len, ha->type); |
3630 | } | 3623 | } |
3631 | } | 3624 | } |
3632 | } | 3625 | } |
3633 | 3626 | ||
3634 | 3627 | static void __hw_addr_flush(struct netdev_hw_addr_list *list) | |
3635 | static void __hw_addr_flush(struct list_head *list) | ||
3636 | { | 3628 | { |
3637 | struct netdev_hw_addr *ha, *tmp; | 3629 | struct netdev_hw_addr *ha, *tmp; |
3638 | 3630 | ||
3639 | list_for_each_entry_safe(ha, tmp, list, list) { | 3631 | list_for_each_entry_safe(ha, tmp, &list->list, list) { |
3640 | list_del_rcu(&ha->list); | 3632 | list_del_rcu(&ha->list); |
3641 | call_rcu(&ha->rcu_head, ha_rcu_free); | 3633 | call_rcu(&ha->rcu_head, ha_rcu_free); |
3642 | } | 3634 | } |
3635 | list->count = 0; | ||
3636 | } | ||
3637 | |||
3638 | static void __hw_addr_init(struct netdev_hw_addr_list *list) | ||
3639 | { | ||
3640 | INIT_LIST_HEAD(&list->list); | ||
3641 | list->count = 0; | ||
3643 | } | 3642 | } |
3644 | 3643 | ||
3645 | /* Device addresses handling functions */ | 3644 | /* Device addresses handling functions */ |
@@ -3648,7 +3647,7 @@ static void dev_addr_flush(struct net_device *dev) | |||
3648 | { | 3647 | { |
3649 | /* rtnl_mutex must be held here */ | 3648 | /* rtnl_mutex must be held here */ |
3650 | 3649 | ||
3651 | __hw_addr_flush(&dev->dev_addr_list); | 3650 | __hw_addr_flush(&dev->dev_addrs); |
3652 | dev->dev_addr = NULL; | 3651 | dev->dev_addr = NULL; |
3653 | } | 3652 | } |
3654 | 3653 | ||
@@ -3660,16 +3659,16 @@ static int dev_addr_init(struct net_device *dev) | |||
3660 | 3659 | ||
3661 | /* rtnl_mutex must be held here */ | 3660 | /* rtnl_mutex must be held here */ |
3662 | 3661 | ||
3663 | INIT_LIST_HEAD(&dev->dev_addr_list); | 3662 | __hw_addr_init(&dev->dev_addrs); |
3664 | memset(addr, 0, sizeof(addr)); | 3663 | memset(addr, 0, sizeof(addr)); |
3665 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(addr), | 3664 | err = __hw_addr_add(&dev->dev_addrs, addr, sizeof(addr), |
3666 | NETDEV_HW_ADDR_T_LAN); | 3665 | NETDEV_HW_ADDR_T_LAN); |
3667 | if (!err) { | 3666 | if (!err) { |
3668 | /* | 3667 | /* |
3669 | * Get the first (previously created) address from the list | 3668 | * Get the first (previously created) address from the list |
3670 | * and set dev_addr pointer to this location. | 3669 | * and set dev_addr pointer to this location. |
3671 | */ | 3670 | */ |
3672 | ha = list_first_entry(&dev->dev_addr_list, | 3671 | ha = list_first_entry(&dev->dev_addrs.list, |
3673 | struct netdev_hw_addr, list); | 3672 | struct netdev_hw_addr, list); |
3674 | dev->dev_addr = ha->addr; | 3673 | dev->dev_addr = ha->addr; |
3675 | } | 3674 | } |
@@ -3694,8 +3693,7 @@ int dev_addr_add(struct net_device *dev, unsigned char *addr, | |||
3694 | 3693 | ||
3695 | ASSERT_RTNL(); | 3694 | ASSERT_RTNL(); |
3696 | 3695 | ||
3697 | err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, dev->addr_len, | 3696 | err = __hw_addr_add(&dev->dev_addrs, addr, dev->addr_len, addr_type); |
3698 | addr_type); | ||
3699 | if (!err) | 3697 | if (!err) |
3700 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 3698 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
3701 | return err; | 3699 | return err; |
@@ -3725,11 +3723,12 @@ int dev_addr_del(struct net_device *dev, unsigned char *addr, | |||
3725 | * We can not remove the first address from the list because | 3723 | * We can not remove the first address from the list because |
3726 | * dev->dev_addr points to that. | 3724 | * dev->dev_addr points to that. |
3727 | */ | 3725 | */ |
3728 | ha = list_first_entry(&dev->dev_addr_list, struct netdev_hw_addr, list); | 3726 | ha = list_first_entry(&dev->dev_addrs.list, |
3727 | struct netdev_hw_addr, list); | ||
3729 | if (ha->addr == dev->dev_addr && ha->refcount == 1) | 3728 | if (ha->addr == dev->dev_addr && ha->refcount == 1) |
3730 | return -ENOENT; | 3729 | return -ENOENT; |
3731 | 3730 | ||
3732 | err = __hw_addr_del(&dev->dev_addr_list, NULL, addr, dev->addr_len, | 3731 | err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, |
3733 | addr_type); | 3732 | addr_type); |
3734 | if (!err) | 3733 | if (!err) |
3735 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 3734 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); |
@@ -3757,8 +3756,7 @@ int dev_addr_add_multiple(struct net_device *to_dev, | |||
3757 | 3756 | ||
3758 | if (from_dev->addr_len != to_dev->addr_len) | 3757 | if (from_dev->addr_len != to_dev->addr_len) |
3759 | return -EINVAL; | 3758 | return -EINVAL; |
3760 | err = __hw_addr_add_multiple(&to_dev->dev_addr_list, NULL, | 3759 | err = __hw_addr_add_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, |
3761 | &from_dev->dev_addr_list, | ||
3762 | to_dev->addr_len, addr_type); | 3760 | to_dev->addr_len, addr_type); |
3763 | if (!err) | 3761 | if (!err) |
3764 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | 3762 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); |
@@ -3784,15 +3782,14 @@ int dev_addr_del_multiple(struct net_device *to_dev, | |||
3784 | 3782 | ||
3785 | if (from_dev->addr_len != to_dev->addr_len) | 3783 | if (from_dev->addr_len != to_dev->addr_len) |
3786 | return -EINVAL; | 3784 | return -EINVAL; |
3787 | __hw_addr_del_multiple(&to_dev->dev_addr_list, NULL, | 3785 | __hw_addr_del_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, |
3788 | &from_dev->dev_addr_list, | ||
3789 | to_dev->addr_len, addr_type); | 3786 | to_dev->addr_len, addr_type); |
3790 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | 3787 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); |
3791 | return 0; | 3788 | return 0; |
3792 | } | 3789 | } |
3793 | EXPORT_SYMBOL(dev_addr_del_multiple); | 3790 | EXPORT_SYMBOL(dev_addr_del_multiple); |
3794 | 3791 | ||
3795 | /* unicast and multicast addresses handling functions */ | 3792 | /* multicast addresses handling functions */ |
3796 | 3793 | ||
3797 | int __dev_addr_delete(struct dev_addr_list **list, int *count, | 3794 | int __dev_addr_delete(struct dev_addr_list **list, int *count, |
3798 | void *addr, int alen, int glbl) | 3795 | void *addr, int alen, int glbl) |
@@ -3868,8 +3865,8 @@ int dev_unicast_delete(struct net_device *dev, void *addr) | |||
3868 | 3865 | ||
3869 | ASSERT_RTNL(); | 3866 | ASSERT_RTNL(); |
3870 | 3867 | ||
3871 | err = __hw_addr_del(&dev->uc_list, &dev->uc_count, addr, | 3868 | err = __hw_addr_del(&dev->uc, addr, dev->addr_len, |
3872 | dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); | 3869 | NETDEV_HW_ADDR_T_UNICAST); |
3873 | if (!err) | 3870 | if (!err) |
3874 | __dev_set_rx_mode(dev); | 3871 | __dev_set_rx_mode(dev); |
3875 | return err; | 3872 | return err; |
@@ -3892,8 +3889,8 @@ int dev_unicast_add(struct net_device *dev, void *addr) | |||
3892 | 3889 | ||
3893 | ASSERT_RTNL(); | 3890 | ASSERT_RTNL(); |
3894 | 3891 | ||
3895 | err = __hw_addr_add(&dev->uc_list, &dev->uc_count, addr, | 3892 | err = __hw_addr_add(&dev->uc, addr, dev->addr_len, |
3896 | dev->addr_len, NETDEV_HW_ADDR_T_UNICAST); | 3893 | NETDEV_HW_ADDR_T_UNICAST); |
3897 | if (!err) | 3894 | if (!err) |
3898 | __dev_set_rx_mode(dev); | 3895 | __dev_set_rx_mode(dev); |
3899 | return err; | 3896 | return err; |
@@ -3966,8 +3963,7 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from) | |||
3966 | if (to->addr_len != from->addr_len) | 3963 | if (to->addr_len != from->addr_len) |
3967 | return -EINVAL; | 3964 | return -EINVAL; |
3968 | 3965 | ||
3969 | err = __hw_addr_sync(&to->uc_list, &to->uc_count, | 3966 | err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); |
3970 | &from->uc_list, &from->uc_count, to->addr_len); | ||
3971 | if (!err) | 3967 | if (!err) |
3972 | __dev_set_rx_mode(to); | 3968 | __dev_set_rx_mode(to); |
3973 | return err; | 3969 | return err; |
@@ -3990,8 +3986,7 @@ void dev_unicast_unsync(struct net_device *to, struct net_device *from) | |||
3990 | if (to->addr_len != from->addr_len) | 3986 | if (to->addr_len != from->addr_len) |
3991 | return; | 3987 | return; |
3992 | 3988 | ||
3993 | __hw_addr_unsync(&to->uc_list, &to->uc_count, | 3989 | __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); |
3994 | &from->uc_list, &from->uc_count, to->addr_len); | ||
3995 | __dev_set_rx_mode(to); | 3990 | __dev_set_rx_mode(to); |
3996 | } | 3991 | } |
3997 | EXPORT_SYMBOL(dev_unicast_unsync); | 3992 | EXPORT_SYMBOL(dev_unicast_unsync); |
@@ -4000,15 +3995,14 @@ static void dev_unicast_flush(struct net_device *dev) | |||
4000 | { | 3995 | { |
4001 | /* rtnl_mutex must be held here */ | 3996 | /* rtnl_mutex must be held here */ |
4002 | 3997 | ||
4003 | __hw_addr_flush(&dev->uc_list); | 3998 | __hw_addr_flush(&dev->uc); |
4004 | dev->uc_count = 0; | ||
4005 | } | 3999 | } |
4006 | 4000 | ||
4007 | static void dev_unicast_init(struct net_device *dev) | 4001 | static void dev_unicast_init(struct net_device *dev) |
4008 | { | 4002 | { |
4009 | /* rtnl_mutex must be held here */ | 4003 | /* rtnl_mutex must be held here */ |
4010 | 4004 | ||
4011 | INIT_LIST_HEAD(&dev->uc_list); | 4005 | __hw_addr_init(&dev->uc); |
4012 | } | 4006 | } |
4013 | 4007 | ||
4014 | 4008 | ||