diff options
-rw-r--r-- | drivers/net/bnx2.c | 4 | ||||
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 4 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 6 | ||||
-rw-r--r-- | drivers/net/mv643xx_eth.c | 2 | ||||
-rw-r--r-- | drivers/net/niu.c | 4 | ||||
-rw-r--r-- | drivers/net/virtio_net.c | 10 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 2 | ||||
-rw-r--r-- | include/linux/netdevice.h | 17 | ||||
-rw-r--r-- | net/core/dev.c | 130 |
9 files changed, 89 insertions, 90 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 7e3738112c4e..38f1c3375d7f 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -3552,14 +3552,14 @@ bnx2_set_rx_mode(struct net_device *dev) | |||
3552 | sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN; | 3552 | sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN; |
3553 | } | 3553 | } |
3554 | 3554 | ||
3555 | if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) { | 3555 | if (dev->uc.count > BNX2_MAX_UNICAST_ADDRESSES) { |
3556 | rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; | 3556 | rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS; |
3557 | sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN | | 3557 | sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN | |
3558 | BNX2_RPM_SORT_USER0_PROM_VLAN; | 3558 | BNX2_RPM_SORT_USER0_PROM_VLAN; |
3559 | } else if (!(dev->flags & IFF_PROMISC)) { | 3559 | } else if (!(dev->flags & IFF_PROMISC)) { |
3560 | /* Add all entries into to the match filter list */ | 3560 | /* Add all entries into to the match filter list */ |
3561 | i = 0; | 3561 | i = 0; |
3562 | list_for_each_entry(ha, &dev->uc_list, list) { | 3562 | list_for_each_entry(ha, &dev->uc.list, list) { |
3563 | bnx2_set_mac_addr(bp, ha->addr, | 3563 | bnx2_set_mac_addr(bp, ha->addr, |
3564 | i + BNX2_START_UNICAST_ADDRESS_INDEX); | 3564 | i + BNX2_START_UNICAST_ADDRESS_INDEX); |
3565 | sort_mode |= (1 << | 3565 | sort_mode |= (1 << |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 8d36743c8140..5e3356f8eb5a 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -2370,7 +2370,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) | |||
2370 | rctl |= E1000_RCTL_VFE; | 2370 | rctl |= E1000_RCTL_VFE; |
2371 | } | 2371 | } |
2372 | 2372 | ||
2373 | if (netdev->uc_count > rar_entries - 1) { | 2373 | if (netdev->uc.count > rar_entries - 1) { |
2374 | rctl |= E1000_RCTL_UPE; | 2374 | rctl |= E1000_RCTL_UPE; |
2375 | } else if (!(netdev->flags & IFF_PROMISC)) { | 2375 | } else if (!(netdev->flags & IFF_PROMISC)) { |
2376 | rctl &= ~E1000_RCTL_UPE; | 2376 | rctl &= ~E1000_RCTL_UPE; |
@@ -2394,7 +2394,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) | |||
2394 | */ | 2394 | */ |
2395 | i = 1; | 2395 | i = 1; |
2396 | if (use_uc) | 2396 | if (use_uc) |
2397 | list_for_each_entry(ha, &netdev->uc_list, list) { | 2397 | list_for_each_entry(ha, &netdev->uc.list, list) { |
2398 | if (i == rar_entries) | 2398 | if (i == rar_entries) |
2399 | break; | 2399 | break; |
2400 | e1000_rar_set(hw, ha->addr, i++); | 2400 | e1000_rar_set(hw, ha->addr, i++); |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a551a96ce676..e756e220db32 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -2321,7 +2321,7 @@ static void ixgbe_set_rx_mode(struct net_device *netdev) | |||
2321 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); | 2321 | IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl); |
2322 | 2322 | ||
2323 | /* reprogram secondary unicast list */ | 2323 | /* reprogram secondary unicast list */ |
2324 | hw->mac.ops.update_uc_addr_list(hw, &netdev->uc_list); | 2324 | hw->mac.ops.update_uc_addr_list(hw, &netdev->uc.list); |
2325 | 2325 | ||
2326 | /* reprogram multicast list */ | 2326 | /* reprogram multicast list */ |
2327 | addr_count = netdev->mc_count; | 2327 | addr_count = netdev->mc_count; |
@@ -5261,7 +5261,7 @@ static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd) | |||
5261 | 5261 | ||
5262 | /** | 5262 | /** |
5263 | * ixgbe_add_sanmac_netdev - Add the SAN MAC address to the corresponding | 5263 | * ixgbe_add_sanmac_netdev - Add the SAN MAC address to the corresponding |
5264 | * netdev->dev_addr_list | 5264 | * netdev->dev_addrs |
5265 | * @netdev: network interface device structure | 5265 | * @netdev: network interface device structure |
5266 | * | 5266 | * |
5267 | * Returns non-zero on failure | 5267 | * Returns non-zero on failure |
@@ -5282,7 +5282,7 @@ static int ixgbe_add_sanmac_netdev(struct net_device *dev) | |||
5282 | 5282 | ||
5283 | /** | 5283 | /** |
5284 | * ixgbe_del_sanmac_netdev - Removes the SAN MAC address to the corresponding | 5284 | * ixgbe_del_sanmac_netdev - Removes the SAN MAC address to the corresponding |
5285 | * netdev->dev_addr_list | 5285 | * netdev->dev_addrs |
5286 | * @netdev: network interface device structure | 5286 | * @netdev: network interface device structure |
5287 | * | 5287 | * |
5288 | * Returns non-zero on failure | 5288 | * Returns non-zero on failure |
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index b4e18a58cb1b..745ae8b4a2e8 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -1729,7 +1729,7 @@ static u32 uc_addr_filter_mask(struct net_device *dev) | |||
1729 | return 0; | 1729 | return 0; |
1730 | 1730 | ||
1731 | nibbles = 1 << (dev->dev_addr[5] & 0x0f); | 1731 | nibbles = 1 << (dev->dev_addr[5] & 0x0f); |
1732 | list_for_each_entry(ha, &dev->uc_list, list) { | 1732 | list_for_each_entry(ha, &dev->uc.list, list) { |
1733 | if (memcmp(dev->dev_addr, ha->addr, 5)) | 1733 | if (memcmp(dev->dev_addr, ha->addr, 5)) |
1734 | return 0; | 1734 | return 0; |
1735 | if ((dev->dev_addr[5] ^ ha->addr[5]) & 0xf0) | 1735 | if ((dev->dev_addr[5] ^ ha->addr[5]) & 0xf0) |
diff --git a/drivers/net/niu.c b/drivers/net/niu.c index fa61a12c5e15..d2146d4a10f3 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c | |||
@@ -6376,7 +6376,7 @@ static void niu_set_rx_mode(struct net_device *dev) | |||
6376 | if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 0)) | 6376 | if ((dev->flags & IFF_ALLMULTI) || (dev->mc_count > 0)) |
6377 | np->flags |= NIU_FLAGS_MCAST; | 6377 | np->flags |= NIU_FLAGS_MCAST; |
6378 | 6378 | ||
6379 | alt_cnt = dev->uc_count; | 6379 | alt_cnt = dev->uc.count; |
6380 | if (alt_cnt > niu_num_alt_addr(np)) { | 6380 | if (alt_cnt > niu_num_alt_addr(np)) { |
6381 | alt_cnt = 0; | 6381 | alt_cnt = 0; |
6382 | np->flags |= NIU_FLAGS_PROMISC; | 6382 | np->flags |= NIU_FLAGS_PROMISC; |
@@ -6385,7 +6385,7 @@ static void niu_set_rx_mode(struct net_device *dev) | |||
6385 | if (alt_cnt) { | 6385 | if (alt_cnt) { |
6386 | int index = 0; | 6386 | int index = 0; |
6387 | 6387 | ||
6388 | list_for_each_entry(ha, &dev->uc_list, list) { | 6388 | list_for_each_entry(ha, &dev->uc.list, list) { |
6389 | err = niu_set_alt_mac(np, index, ha->addr); | 6389 | err = niu_set_alt_mac(np, index, ha->addr); |
6390 | if (err) | 6390 | if (err) |
6391 | printk(KERN_WARNING PFX "%s: Error %d " | 6391 | printk(KERN_WARNING PFX "%s: Error %d " |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 52198f6797a4..2a6e81d5b579 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -709,7 +709,7 @@ static void virtnet_set_rx_mode(struct net_device *dev) | |||
709 | allmulti ? "en" : "dis"); | 709 | allmulti ? "en" : "dis"); |
710 | 710 | ||
711 | /* MAC filter - use one buffer for both lists */ | 711 | /* MAC filter - use one buffer for both lists */ |
712 | mac_data = buf = kzalloc(((dev->uc_count + dev->mc_count) * ETH_ALEN) + | 712 | mac_data = buf = kzalloc(((dev->uc.count + dev->mc_count) * ETH_ALEN) + |
713 | (2 * sizeof(mac_data->entries)), GFP_ATOMIC); | 713 | (2 * sizeof(mac_data->entries)), GFP_ATOMIC); |
714 | if (!buf) { | 714 | if (!buf) { |
715 | dev_warn(&dev->dev, "No memory for MAC address buffer\n"); | 715 | dev_warn(&dev->dev, "No memory for MAC address buffer\n"); |
@@ -719,16 +719,16 @@ static void virtnet_set_rx_mode(struct net_device *dev) | |||
719 | sg_init_table(sg, 2); | 719 | sg_init_table(sg, 2); |
720 | 720 | ||
721 | /* Store the unicast list and count in the front of the buffer */ | 721 | /* Store the unicast list and count in the front of the buffer */ |
722 | mac_data->entries = dev->uc_count; | 722 | mac_data->entries = dev->uc.count; |
723 | i = 0; | 723 | i = 0; |
724 | list_for_each_entry(ha, &dev->uc_list, list) | 724 | list_for_each_entry(ha, &dev->uc.list, list) |
725 | memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN); | 725 | memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN); |
726 | 726 | ||
727 | sg_set_buf(&sg[0], mac_data, | 727 | sg_set_buf(&sg[0], mac_data, |
728 | sizeof(mac_data->entries) + (dev->uc_count * ETH_ALEN)); | 728 | sizeof(mac_data->entries) + (dev->uc.count * ETH_ALEN)); |
729 | 729 | ||
730 | /* multicast list and count fill the end */ | 730 | /* multicast list and count fill the end */ |
731 | mac_data = (void *)&mac_data->macs[dev->uc_count][0]; | 731 | mac_data = (void *)&mac_data->macs[dev->uc.count][0]; |
732 | 732 | ||
733 | mac_data->entries = dev->mc_count; | 733 | mac_data->entries = dev->mc_count; |
734 | addr = dev->mc_list; | 734 | addr = dev->mc_list; |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index ecd3d06c0d5c..3607d107f490 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -655,7 +655,7 @@ static void qeth_l2_set_multicast_list(struct net_device *dev) | |||
655 | for (dm = dev->mc_list; dm; dm = dm->next) | 655 | for (dm = dev->mc_list; dm; dm = dm->next) |
656 | qeth_l2_add_mc(card, dm->da_addr, 0); | 656 | qeth_l2_add_mc(card, dm->da_addr, 0); |
657 | 657 | ||
658 | list_for_each_entry(ha, &dev->uc_list, list) | 658 | list_for_each_entry(ha, &dev->uc.list, list) |
659 | qeth_l2_add_mc(card, ha->addr, 1); | 659 | qeth_l2_add_mc(card, ha->addr, 1); |
660 | 660 | ||
661 | spin_unlock_bh(&card->mclock); | 661 | spin_unlock_bh(&card->mclock); |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 9ea8d6dfe540..d4a4d9867794 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -224,6 +224,11 @@ struct netdev_hw_addr { | |||
224 | struct rcu_head rcu_head; | 224 | struct rcu_head rcu_head; |
225 | }; | 225 | }; |
226 | 226 | ||
227 | struct netdev_hw_addr_list { | ||
228 | struct list_head list; | ||
229 | int count; | ||
230 | }; | ||
231 | |||
227 | struct hh_cache | 232 | struct hh_cache |
228 | { | 233 | { |
229 | struct hh_cache *hh_next; /* Next entry */ | 234 | struct hh_cache *hh_next; /* Next entry */ |
@@ -776,9 +781,8 @@ struct net_device | |||
776 | unsigned char addr_len; /* hardware address length */ | 781 | unsigned char addr_len; /* hardware address length */ |
777 | unsigned short dev_id; /* for shared network cards */ | 782 | unsigned short dev_id; /* for shared network cards */ |
778 | 783 | ||
779 | struct list_head uc_list; /* Secondary unicast mac | 784 | struct netdev_hw_addr_list uc; /* Secondary unicast |
780 | addresses */ | 785 | mac addresses */ |
781 | int uc_count; /* Number of installed ucasts */ | ||
782 | int uc_promisc; | 786 | int uc_promisc; |
783 | spinlock_t addr_list_lock; | 787 | spinlock_t addr_list_lock; |
784 | struct dev_addr_list *mc_list; /* Multicast mac addresses */ | 788 | struct dev_addr_list *mc_list; /* Multicast mac addresses */ |
@@ -810,7 +814,8 @@ struct net_device | |||
810 | because most packets are | 814 | because most packets are |
811 | unicast) */ | 815 | unicast) */ |
812 | 816 | ||
813 | struct list_head dev_addr_list; /* list of device hw addresses */ | 817 | struct netdev_hw_addr_list dev_addrs; /* list of device |
818 | hw addresses */ | ||
814 | 819 | ||
815 | unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ | 820 | unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */ |
816 | 821 | ||
@@ -1806,11 +1811,11 @@ static inline void netif_addr_unlock_bh(struct net_device *dev) | |||
1806 | } | 1811 | } |
1807 | 1812 | ||
1808 | /* | 1813 | /* |
1809 | * dev_addr_list walker. Should be used only for read access. Call with | 1814 | * dev_addrs walker. Should be used only for read access. Call with |
1810 | * rcu_read_lock held. | 1815 | * rcu_read_lock held. |
1811 | */ | 1816 | */ |
1812 | #define for_each_dev_addr(dev, ha) \ | 1817 | #define for_each_dev_addr(dev, ha) \ |
1813 | list_for_each_entry_rcu(ha, &dev->dev_addr_list, list) | 1818 | list_for_each_entry_rcu(ha, &dev->dev_addrs.list, list) |
1814 | 1819 | ||
1815 | /* These functions live elsewhere (drivers/net/net_init.c, but related) */ | 1820 | /* These functions live elsewhere (drivers/net/net_init.c, but related) */ |
1816 | 1821 | ||
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 | ||