diff options
author | Jiri Pirko <jpirko@redhat.com> | 2010-04-01 17:22:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-03 17:22:11 -0400 |
commit | a748ee2426817a95b1f03012d8f339c45c722ae1 (patch) | |
tree | 37cb9f8836f05bd49b86eb52ddeff3e98185cc58 /net | |
parent | 9fc4178b149ae8b0a2fbf83f2f4df3cf8789177b (diff) |
net: move address list functions to a separate file
+little renaming of unicast functions to be smooth with multicast ones
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/8021q/vlan.c | 4 | ||||
-rw-r--r-- | net/8021q/vlan_dev.c | 14 | ||||
-rw-r--r-- | net/core/Makefile | 3 | ||||
-rw-r--r-- | net/core/dev.c | 430 | ||||
-rw-r--r-- | net/core/dev_addr_lists.c | 478 | ||||
-rw-r--r-- | net/dsa/slave.c | 14 | ||||
-rw-r--r-- | net/packet/af_packet.c | 4 |
7 files changed, 501 insertions, 446 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index c39a5f41169c..bd33f02013ec 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -356,13 +356,13 @@ static void vlan_sync_address(struct net_device *dev, | |||
356 | * the new address */ | 356 | * the new address */ |
357 | if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && | 357 | if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && |
358 | !compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) | 358 | !compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) |
359 | dev_unicast_delete(dev, vlandev->dev_addr); | 359 | dev_uc_del(dev, vlandev->dev_addr); |
360 | 360 | ||
361 | /* vlan address was equal to the old address and is different from | 361 | /* vlan address was equal to the old address and is different from |
362 | * the new address */ | 362 | * the new address */ |
363 | if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && | 363 | if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) && |
364 | compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) | 364 | compare_ether_addr(vlandev->dev_addr, dev->dev_addr)) |
365 | dev_unicast_add(dev, vlandev->dev_addr); | 365 | dev_uc_add(dev, vlandev->dev_addr); |
366 | 366 | ||
367 | memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); | 367 | memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN); |
368 | } | 368 | } |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 9e83272fc5b0..7f4d247237e4 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -461,7 +461,7 @@ static int vlan_dev_open(struct net_device *dev) | |||
461 | return -ENETDOWN; | 461 | return -ENETDOWN; |
462 | 462 | ||
463 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { | 463 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { |
464 | err = dev_unicast_add(real_dev, dev->dev_addr); | 464 | err = dev_uc_add(real_dev, dev->dev_addr); |
465 | if (err < 0) | 465 | if (err < 0) |
466 | goto out; | 466 | goto out; |
467 | } | 467 | } |
@@ -490,7 +490,7 @@ clear_allmulti: | |||
490 | dev_set_allmulti(real_dev, -1); | 490 | dev_set_allmulti(real_dev, -1); |
491 | del_unicast: | 491 | del_unicast: |
492 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | 492 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
493 | dev_unicast_delete(real_dev, dev->dev_addr); | 493 | dev_uc_del(real_dev, dev->dev_addr); |
494 | out: | 494 | out: |
495 | netif_carrier_off(dev); | 495 | netif_carrier_off(dev); |
496 | return err; | 496 | return err; |
@@ -505,14 +505,14 @@ static int vlan_dev_stop(struct net_device *dev) | |||
505 | vlan_gvrp_request_leave(dev); | 505 | vlan_gvrp_request_leave(dev); |
506 | 506 | ||
507 | dev_mc_unsync(real_dev, dev); | 507 | dev_mc_unsync(real_dev, dev); |
508 | dev_unicast_unsync(real_dev, dev); | 508 | dev_uc_unsync(real_dev, dev); |
509 | if (dev->flags & IFF_ALLMULTI) | 509 | if (dev->flags & IFF_ALLMULTI) |
510 | dev_set_allmulti(real_dev, -1); | 510 | dev_set_allmulti(real_dev, -1); |
511 | if (dev->flags & IFF_PROMISC) | 511 | if (dev->flags & IFF_PROMISC) |
512 | dev_set_promiscuity(real_dev, -1); | 512 | dev_set_promiscuity(real_dev, -1); |
513 | 513 | ||
514 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | 514 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
515 | dev_unicast_delete(real_dev, dev->dev_addr); | 515 | dev_uc_del(real_dev, dev->dev_addr); |
516 | 516 | ||
517 | netif_carrier_off(dev); | 517 | netif_carrier_off(dev); |
518 | return 0; | 518 | return 0; |
@@ -531,13 +531,13 @@ static int vlan_dev_set_mac_address(struct net_device *dev, void *p) | |||
531 | goto out; | 531 | goto out; |
532 | 532 | ||
533 | if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { | 533 | if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { |
534 | err = dev_unicast_add(real_dev, addr->sa_data); | 534 | err = dev_uc_add(real_dev, addr->sa_data); |
535 | if (err < 0) | 535 | if (err < 0) |
536 | return err; | 536 | return err; |
537 | } | 537 | } |
538 | 538 | ||
539 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | 539 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) |
540 | dev_unicast_delete(real_dev, dev->dev_addr); | 540 | dev_uc_del(real_dev, dev->dev_addr); |
541 | 541 | ||
542 | out: | 542 | out: |
543 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | 543 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
@@ -654,7 +654,7 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change) | |||
654 | static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) | 654 | static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) |
655 | { | 655 | { |
656 | dev_mc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); | 656 | dev_mc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); |
657 | dev_unicast_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); | 657 | dev_uc_sync(vlan_dev_info(vlan_dev)->real_dev, vlan_dev); |
658 | } | 658 | } |
659 | 659 | ||
660 | /* | 660 | /* |
diff --git a/net/core/Makefile b/net/core/Makefile index 08791ac3e05a..0a899f1aadb9 100644 --- a/net/core/Makefile +++ b/net/core/Makefile | |||
@@ -8,7 +8,8 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ | |||
8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o | 8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o |
9 | 9 | ||
10 | obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \ | 10 | obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \ |
11 | neighbour.o rtnetlink.o utils.o link_watch.o filter.o | 11 | neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ |
12 | dev_addr_lists.o | ||
12 | 13 | ||
13 | obj-$(CONFIG_XFRM) += flow.o | 14 | obj-$(CONFIG_XFRM) += flow.o |
14 | obj-y += net-sysfs.o | 15 | obj-y += net-sysfs.o |
diff --git a/net/core/dev.c b/net/core/dev.c index c6b52068d5ec..949c62dba719 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3968,314 +3968,6 @@ void dev_set_rx_mode(struct net_device *dev) | |||
3968 | netif_addr_unlock_bh(dev); | 3968 | netif_addr_unlock_bh(dev); |
3969 | } | 3969 | } |
3970 | 3970 | ||
3971 | /* hw addresses list handling functions */ | ||
3972 | |||
3973 | static int __hw_addr_add(struct netdev_hw_addr_list *list, unsigned char *addr, | ||
3974 | int addr_len, unsigned char addr_type) | ||
3975 | { | ||
3976 | struct netdev_hw_addr *ha; | ||
3977 | int alloc_size; | ||
3978 | |||
3979 | if (addr_len > MAX_ADDR_LEN) | ||
3980 | return -EINVAL; | ||
3981 | |||
3982 | list_for_each_entry(ha, &list->list, list) { | ||
3983 | if (!memcmp(ha->addr, addr, addr_len) && | ||
3984 | ha->type == addr_type) { | ||
3985 | ha->refcount++; | ||
3986 | return 0; | ||
3987 | } | ||
3988 | } | ||
3989 | |||
3990 | |||
3991 | alloc_size = sizeof(*ha); | ||
3992 | if (alloc_size < L1_CACHE_BYTES) | ||
3993 | alloc_size = L1_CACHE_BYTES; | ||
3994 | ha = kmalloc(alloc_size, GFP_ATOMIC); | ||
3995 | if (!ha) | ||
3996 | return -ENOMEM; | ||
3997 | memcpy(ha->addr, addr, addr_len); | ||
3998 | ha->type = addr_type; | ||
3999 | ha->refcount = 1; | ||
4000 | ha->synced = false; | ||
4001 | list_add_tail_rcu(&ha->list, &list->list); | ||
4002 | list->count++; | ||
4003 | return 0; | ||
4004 | } | ||
4005 | |||
4006 | static void ha_rcu_free(struct rcu_head *head) | ||
4007 | { | ||
4008 | struct netdev_hw_addr *ha; | ||
4009 | |||
4010 | ha = container_of(head, struct netdev_hw_addr, rcu_head); | ||
4011 | kfree(ha); | ||
4012 | } | ||
4013 | |||
4014 | static int __hw_addr_del(struct netdev_hw_addr_list *list, unsigned char *addr, | ||
4015 | int addr_len, unsigned char addr_type) | ||
4016 | { | ||
4017 | struct netdev_hw_addr *ha; | ||
4018 | |||
4019 | list_for_each_entry(ha, &list->list, list) { | ||
4020 | if (!memcmp(ha->addr, addr, addr_len) && | ||
4021 | (ha->type == addr_type || !addr_type)) { | ||
4022 | if (--ha->refcount) | ||
4023 | return 0; | ||
4024 | list_del_rcu(&ha->list); | ||
4025 | call_rcu(&ha->rcu_head, ha_rcu_free); | ||
4026 | list->count--; | ||
4027 | return 0; | ||
4028 | } | ||
4029 | } | ||
4030 | return -ENOENT; | ||
4031 | } | ||
4032 | |||
4033 | static int __hw_addr_add_multiple(struct netdev_hw_addr_list *to_list, | ||
4034 | struct netdev_hw_addr_list *from_list, | ||
4035 | int addr_len, | ||
4036 | unsigned char addr_type) | ||
4037 | { | ||
4038 | int err; | ||
4039 | struct netdev_hw_addr *ha, *ha2; | ||
4040 | unsigned char type; | ||
4041 | |||
4042 | list_for_each_entry(ha, &from_list->list, list) { | ||
4043 | type = addr_type ? addr_type : ha->type; | ||
4044 | err = __hw_addr_add(to_list, ha->addr, addr_len, type); | ||
4045 | if (err) | ||
4046 | goto unroll; | ||
4047 | } | ||
4048 | return 0; | ||
4049 | |||
4050 | unroll: | ||
4051 | list_for_each_entry(ha2, &from_list->list, list) { | ||
4052 | if (ha2 == ha) | ||
4053 | break; | ||
4054 | type = addr_type ? addr_type : ha2->type; | ||
4055 | __hw_addr_del(to_list, ha2->addr, addr_len, type); | ||
4056 | } | ||
4057 | return err; | ||
4058 | } | ||
4059 | |||
4060 | static void __hw_addr_del_multiple(struct netdev_hw_addr_list *to_list, | ||
4061 | struct netdev_hw_addr_list *from_list, | ||
4062 | int addr_len, | ||
4063 | unsigned char addr_type) | ||
4064 | { | ||
4065 | struct netdev_hw_addr *ha; | ||
4066 | unsigned char type; | ||
4067 | |||
4068 | list_for_each_entry(ha, &from_list->list, list) { | ||
4069 | type = addr_type ? addr_type : ha->type; | ||
4070 | __hw_addr_del(to_list, ha->addr, addr_len, addr_type); | ||
4071 | } | ||
4072 | } | ||
4073 | |||
4074 | static int __hw_addr_sync(struct netdev_hw_addr_list *to_list, | ||
4075 | struct netdev_hw_addr_list *from_list, | ||
4076 | int addr_len) | ||
4077 | { | ||
4078 | int err = 0; | ||
4079 | struct netdev_hw_addr *ha, *tmp; | ||
4080 | |||
4081 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { | ||
4082 | if (!ha->synced) { | ||
4083 | err = __hw_addr_add(to_list, ha->addr, | ||
4084 | addr_len, ha->type); | ||
4085 | if (err) | ||
4086 | break; | ||
4087 | ha->synced = true; | ||
4088 | ha->refcount++; | ||
4089 | } else if (ha->refcount == 1) { | ||
4090 | __hw_addr_del(to_list, ha->addr, addr_len, ha->type); | ||
4091 | __hw_addr_del(from_list, ha->addr, addr_len, ha->type); | ||
4092 | } | ||
4093 | } | ||
4094 | return err; | ||
4095 | } | ||
4096 | |||
4097 | static void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, | ||
4098 | struct netdev_hw_addr_list *from_list, | ||
4099 | int addr_len) | ||
4100 | { | ||
4101 | struct netdev_hw_addr *ha, *tmp; | ||
4102 | |||
4103 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { | ||
4104 | if (ha->synced) { | ||
4105 | __hw_addr_del(to_list, ha->addr, | ||
4106 | addr_len, ha->type); | ||
4107 | ha->synced = false; | ||
4108 | __hw_addr_del(from_list, ha->addr, | ||
4109 | addr_len, ha->type); | ||
4110 | } | ||
4111 | } | ||
4112 | } | ||
4113 | |||
4114 | static void __hw_addr_flush(struct netdev_hw_addr_list *list) | ||
4115 | { | ||
4116 | struct netdev_hw_addr *ha, *tmp; | ||
4117 | |||
4118 | list_for_each_entry_safe(ha, tmp, &list->list, list) { | ||
4119 | list_del_rcu(&ha->list); | ||
4120 | call_rcu(&ha->rcu_head, ha_rcu_free); | ||
4121 | } | ||
4122 | list->count = 0; | ||
4123 | } | ||
4124 | |||
4125 | static void __hw_addr_init(struct netdev_hw_addr_list *list) | ||
4126 | { | ||
4127 | INIT_LIST_HEAD(&list->list); | ||
4128 | list->count = 0; | ||
4129 | } | ||
4130 | |||
4131 | /* Device addresses handling functions */ | ||
4132 | |||
4133 | static void dev_addr_flush(struct net_device *dev) | ||
4134 | { | ||
4135 | /* rtnl_mutex must be held here */ | ||
4136 | |||
4137 | __hw_addr_flush(&dev->dev_addrs); | ||
4138 | dev->dev_addr = NULL; | ||
4139 | } | ||
4140 | |||
4141 | static int dev_addr_init(struct net_device *dev) | ||
4142 | { | ||
4143 | unsigned char addr[MAX_ADDR_LEN]; | ||
4144 | struct netdev_hw_addr *ha; | ||
4145 | int err; | ||
4146 | |||
4147 | /* rtnl_mutex must be held here */ | ||
4148 | |||
4149 | __hw_addr_init(&dev->dev_addrs); | ||
4150 | memset(addr, 0, sizeof(addr)); | ||
4151 | err = __hw_addr_add(&dev->dev_addrs, addr, sizeof(addr), | ||
4152 | NETDEV_HW_ADDR_T_LAN); | ||
4153 | if (!err) { | ||
4154 | /* | ||
4155 | * Get the first (previously created) address from the list | ||
4156 | * and set dev_addr pointer to this location. | ||
4157 | */ | ||
4158 | ha = list_first_entry(&dev->dev_addrs.list, | ||
4159 | struct netdev_hw_addr, list); | ||
4160 | dev->dev_addr = ha->addr; | ||
4161 | } | ||
4162 | return err; | ||
4163 | } | ||
4164 | |||
4165 | /** | ||
4166 | * dev_addr_add - Add a device address | ||
4167 | * @dev: device | ||
4168 | * @addr: address to add | ||
4169 | * @addr_type: address type | ||
4170 | * | ||
4171 | * Add a device address to the device or increase the reference count if | ||
4172 | * it already exists. | ||
4173 | * | ||
4174 | * The caller must hold the rtnl_mutex. | ||
4175 | */ | ||
4176 | int dev_addr_add(struct net_device *dev, unsigned char *addr, | ||
4177 | unsigned char addr_type) | ||
4178 | { | ||
4179 | int err; | ||
4180 | |||
4181 | ASSERT_RTNL(); | ||
4182 | |||
4183 | err = __hw_addr_add(&dev->dev_addrs, addr, dev->addr_len, addr_type); | ||
4184 | if (!err) | ||
4185 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | ||
4186 | return err; | ||
4187 | } | ||
4188 | EXPORT_SYMBOL(dev_addr_add); | ||
4189 | |||
4190 | /** | ||
4191 | * dev_addr_del - Release a device address. | ||
4192 | * @dev: device | ||
4193 | * @addr: address to delete | ||
4194 | * @addr_type: address type | ||
4195 | * | ||
4196 | * Release reference to a device address and remove it from the device | ||
4197 | * if the reference count drops to zero. | ||
4198 | * | ||
4199 | * The caller must hold the rtnl_mutex. | ||
4200 | */ | ||
4201 | int dev_addr_del(struct net_device *dev, unsigned char *addr, | ||
4202 | unsigned char addr_type) | ||
4203 | { | ||
4204 | int err; | ||
4205 | struct netdev_hw_addr *ha; | ||
4206 | |||
4207 | ASSERT_RTNL(); | ||
4208 | |||
4209 | /* | ||
4210 | * We can not remove the first address from the list because | ||
4211 | * dev->dev_addr points to that. | ||
4212 | */ | ||
4213 | ha = list_first_entry(&dev->dev_addrs.list, | ||
4214 | struct netdev_hw_addr, list); | ||
4215 | if (ha->addr == dev->dev_addr && ha->refcount == 1) | ||
4216 | return -ENOENT; | ||
4217 | |||
4218 | err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, | ||
4219 | addr_type); | ||
4220 | if (!err) | ||
4221 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | ||
4222 | return err; | ||
4223 | } | ||
4224 | EXPORT_SYMBOL(dev_addr_del); | ||
4225 | |||
4226 | /** | ||
4227 | * dev_addr_add_multiple - Add device addresses from another device | ||
4228 | * @to_dev: device to which addresses will be added | ||
4229 | * @from_dev: device from which addresses will be added | ||
4230 | * @addr_type: address type - 0 means type will be used from from_dev | ||
4231 | * | ||
4232 | * Add device addresses of the one device to another. | ||
4233 | ** | ||
4234 | * The caller must hold the rtnl_mutex. | ||
4235 | */ | ||
4236 | int dev_addr_add_multiple(struct net_device *to_dev, | ||
4237 | struct net_device *from_dev, | ||
4238 | unsigned char addr_type) | ||
4239 | { | ||
4240 | int err; | ||
4241 | |||
4242 | ASSERT_RTNL(); | ||
4243 | |||
4244 | if (from_dev->addr_len != to_dev->addr_len) | ||
4245 | return -EINVAL; | ||
4246 | err = __hw_addr_add_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, | ||
4247 | to_dev->addr_len, addr_type); | ||
4248 | if (!err) | ||
4249 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | ||
4250 | return err; | ||
4251 | } | ||
4252 | EXPORT_SYMBOL(dev_addr_add_multiple); | ||
4253 | |||
4254 | /** | ||
4255 | * dev_addr_del_multiple - Delete device addresses by another device | ||
4256 | * @to_dev: device where the addresses will be deleted | ||
4257 | * @from_dev: device by which addresses the addresses will be deleted | ||
4258 | * @addr_type: address type - 0 means type will used from from_dev | ||
4259 | * | ||
4260 | * Deletes addresses in to device by the list of addresses in from device. | ||
4261 | * | ||
4262 | * The caller must hold the rtnl_mutex. | ||
4263 | */ | ||
4264 | int dev_addr_del_multiple(struct net_device *to_dev, | ||
4265 | struct net_device *from_dev, | ||
4266 | unsigned char addr_type) | ||
4267 | { | ||
4268 | ASSERT_RTNL(); | ||
4269 | |||
4270 | if (from_dev->addr_len != to_dev->addr_len) | ||
4271 | return -EINVAL; | ||
4272 | __hw_addr_del_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, | ||
4273 | to_dev->addr_len, addr_type); | ||
4274 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | ||
4275 | return 0; | ||
4276 | } | ||
4277 | EXPORT_SYMBOL(dev_addr_del_multiple); | ||
4278 | |||
4279 | /* multicast addresses handling functions */ | 3971 | /* multicast addresses handling functions */ |
4280 | 3972 | ||
4281 | int __dev_addr_delete(struct dev_addr_list **list, int *count, | 3973 | int __dev_addr_delete(struct dev_addr_list **list, int *count, |
@@ -4336,57 +4028,6 @@ int __dev_addr_add(struct dev_addr_list **list, int *count, | |||
4336 | return 0; | 4028 | return 0; |
4337 | } | 4029 | } |
4338 | 4030 | ||
4339 | /** | ||
4340 | * dev_unicast_delete - Release secondary unicast address. | ||
4341 | * @dev: device | ||
4342 | * @addr: address to delete | ||
4343 | * | ||
4344 | * Release reference to a secondary unicast address and remove it | ||
4345 | * from the device if the reference count drops to zero. | ||
4346 | * | ||
4347 | * The caller must hold the rtnl_mutex. | ||
4348 | */ | ||
4349 | int dev_unicast_delete(struct net_device *dev, void *addr) | ||
4350 | { | ||
4351 | int err; | ||
4352 | |||
4353 | ASSERT_RTNL(); | ||
4354 | |||
4355 | netif_addr_lock_bh(dev); | ||
4356 | err = __hw_addr_del(&dev->uc, addr, dev->addr_len, | ||
4357 | NETDEV_HW_ADDR_T_UNICAST); | ||
4358 | if (!err) | ||
4359 | __dev_set_rx_mode(dev); | ||
4360 | netif_addr_unlock_bh(dev); | ||
4361 | return err; | ||
4362 | } | ||
4363 | EXPORT_SYMBOL(dev_unicast_delete); | ||
4364 | |||
4365 | /** | ||
4366 | * dev_unicast_add - add a secondary unicast address | ||
4367 | * @dev: device | ||
4368 | * @addr: address to add | ||
4369 | * | ||
4370 | * Add a secondary unicast address to the device or increase | ||
4371 | * the reference count if it already exists. | ||
4372 | * | ||
4373 | * The caller must hold the rtnl_mutex. | ||
4374 | */ | ||
4375 | int dev_unicast_add(struct net_device *dev, void *addr) | ||
4376 | { | ||
4377 | int err; | ||
4378 | |||
4379 | ASSERT_RTNL(); | ||
4380 | |||
4381 | netif_addr_lock_bh(dev); | ||
4382 | err = __hw_addr_add(&dev->uc, addr, dev->addr_len, | ||
4383 | NETDEV_HW_ADDR_T_UNICAST); | ||
4384 | if (!err) | ||
4385 | __dev_set_rx_mode(dev); | ||
4386 | netif_addr_unlock_bh(dev); | ||
4387 | return err; | ||
4388 | } | ||
4389 | EXPORT_SYMBOL(dev_unicast_add); | ||
4390 | 4031 | ||
4391 | int __dev_addr_sync(struct dev_addr_list **to, int *to_count, | 4032 | int __dev_addr_sync(struct dev_addr_list **to, int *to_count, |
4392 | struct dev_addr_list **from, int *from_count) | 4033 | struct dev_addr_list **from, int *from_count) |
@@ -4436,71 +4077,6 @@ void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, | |||
4436 | } | 4077 | } |
4437 | EXPORT_SYMBOL_GPL(__dev_addr_unsync); | 4078 | EXPORT_SYMBOL_GPL(__dev_addr_unsync); |
4438 | 4079 | ||
4439 | /** | ||
4440 | * dev_unicast_sync - Synchronize device's unicast list to another device | ||
4441 | * @to: destination device | ||
4442 | * @from: source device | ||
4443 | * | ||
4444 | * Add newly added addresses to the destination device and release | ||
4445 | * addresses that have no users left. The source device must be | ||
4446 | * locked by netif_tx_lock_bh. | ||
4447 | * | ||
4448 | * This function is intended to be called from the dev->set_rx_mode | ||
4449 | * function of layered software devices. | ||
4450 | */ | ||
4451 | int dev_unicast_sync(struct net_device *to, struct net_device *from) | ||
4452 | { | ||
4453 | int err = 0; | ||
4454 | |||
4455 | if (to->addr_len != from->addr_len) | ||
4456 | return -EINVAL; | ||
4457 | |||
4458 | netif_addr_lock_bh(to); | ||
4459 | err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); | ||
4460 | if (!err) | ||
4461 | __dev_set_rx_mode(to); | ||
4462 | netif_addr_unlock_bh(to); | ||
4463 | return err; | ||
4464 | } | ||
4465 | EXPORT_SYMBOL(dev_unicast_sync); | ||
4466 | |||
4467 | /** | ||
4468 | * dev_unicast_unsync - Remove synchronized addresses from the destination device | ||
4469 | * @to: destination device | ||
4470 | * @from: source device | ||
4471 | * | ||
4472 | * Remove all addresses that were added to the destination device by | ||
4473 | * dev_unicast_sync(). This function is intended to be called from the | ||
4474 | * dev->stop function of layered software devices. | ||
4475 | */ | ||
4476 | void dev_unicast_unsync(struct net_device *to, struct net_device *from) | ||
4477 | { | ||
4478 | if (to->addr_len != from->addr_len) | ||
4479 | return; | ||
4480 | |||
4481 | netif_addr_lock_bh(from); | ||
4482 | netif_addr_lock(to); | ||
4483 | __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); | ||
4484 | __dev_set_rx_mode(to); | ||
4485 | netif_addr_unlock(to); | ||
4486 | netif_addr_unlock_bh(from); | ||
4487 | } | ||
4488 | EXPORT_SYMBOL(dev_unicast_unsync); | ||
4489 | |||
4490 | void dev_unicast_flush(struct net_device *dev) | ||
4491 | { | ||
4492 | netif_addr_lock_bh(dev); | ||
4493 | __hw_addr_flush(&dev->uc); | ||
4494 | netif_addr_unlock_bh(dev); | ||
4495 | } | ||
4496 | EXPORT_SYMBOL(dev_unicast_flush); | ||
4497 | |||
4498 | static void dev_unicast_init(struct net_device *dev) | ||
4499 | { | ||
4500 | __hw_addr_init(&dev->uc); | ||
4501 | } | ||
4502 | |||
4503 | |||
4504 | static void __dev_addr_discard(struct dev_addr_list **list) | 4080 | static void __dev_addr_discard(struct dev_addr_list **list) |
4505 | { | 4081 | { |
4506 | struct dev_addr_list *tmp; | 4082 | struct dev_addr_list *tmp; |
@@ -5153,7 +4729,7 @@ static void rollback_registered_many(struct list_head *head) | |||
5153 | /* | 4729 | /* |
5154 | * Flush the unicast and multicast chains | 4730 | * Flush the unicast and multicast chains |
5155 | */ | 4731 | */ |
5156 | dev_unicast_flush(dev); | 4732 | dev_uc_flush(dev); |
5157 | dev_addr_discard(dev); | 4733 | dev_addr_discard(dev); |
5158 | 4734 | ||
5159 | if (dev->netdev_ops->ndo_uninit) | 4735 | if (dev->netdev_ops->ndo_uninit) |
@@ -5734,7 +5310,7 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name, | |||
5734 | if (dev_addr_init(dev)) | 5310 | if (dev_addr_init(dev)) |
5735 | goto free_rx; | 5311 | goto free_rx; |
5736 | 5312 | ||
5737 | dev_unicast_init(dev); | 5313 | dev_uc_init(dev); |
5738 | 5314 | ||
5739 | dev_net_set(dev, &init_net); | 5315 | dev_net_set(dev, &init_net); |
5740 | 5316 | ||
@@ -5968,7 +5544,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | |||
5968 | /* | 5544 | /* |
5969 | * Flush the unicast and multicast chains | 5545 | * Flush the unicast and multicast chains |
5970 | */ | 5546 | */ |
5971 | dev_unicast_flush(dev); | 5547 | dev_uc_flush(dev); |
5972 | dev_addr_discard(dev); | 5548 | dev_addr_discard(dev); |
5973 | 5549 | ||
5974 | netdev_unregister_kobject(dev); | 5550 | netdev_unregister_kobject(dev); |
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c new file mode 100644 index 000000000000..7e52b6d18add --- /dev/null +++ b/net/core/dev_addr_lists.c | |||
@@ -0,0 +1,478 @@ | |||
1 | /* | ||
2 | * net/core/dev_addr_lists.c - Functions for handling net device lists | ||
3 | * Copyright (c) 2010 Jiri Pirko <jpirko@redhat.com> | ||
4 | * | ||
5 | * This file contains functions for working with unicast, multicast and device | ||
6 | * addresses lists. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/netdevice.h> | ||
15 | #include <linux/rtnetlink.h> | ||
16 | #include <linux/list.h> | ||
17 | |||
18 | /* | ||
19 | * General list handling functions | ||
20 | */ | ||
21 | |||
22 | static int __hw_addr_add(struct netdev_hw_addr_list *list, unsigned char *addr, | ||
23 | int addr_len, unsigned char addr_type) | ||
24 | { | ||
25 | struct netdev_hw_addr *ha; | ||
26 | int alloc_size; | ||
27 | |||
28 | if (addr_len > MAX_ADDR_LEN) | ||
29 | return -EINVAL; | ||
30 | |||
31 | list_for_each_entry(ha, &list->list, list) { | ||
32 | if (!memcmp(ha->addr, addr, addr_len) && | ||
33 | ha->type == addr_type) { | ||
34 | ha->refcount++; | ||
35 | return 0; | ||
36 | } | ||
37 | } | ||
38 | |||
39 | |||
40 | alloc_size = sizeof(*ha); | ||
41 | if (alloc_size < L1_CACHE_BYTES) | ||
42 | alloc_size = L1_CACHE_BYTES; | ||
43 | ha = kmalloc(alloc_size, GFP_ATOMIC); | ||
44 | if (!ha) | ||
45 | return -ENOMEM; | ||
46 | memcpy(ha->addr, addr, addr_len); | ||
47 | ha->type = addr_type; | ||
48 | ha->refcount = 1; | ||
49 | ha->synced = false; | ||
50 | list_add_tail_rcu(&ha->list, &list->list); | ||
51 | list->count++; | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static void ha_rcu_free(struct rcu_head *head) | ||
56 | { | ||
57 | struct netdev_hw_addr *ha; | ||
58 | |||
59 | ha = container_of(head, struct netdev_hw_addr, rcu_head); | ||
60 | kfree(ha); | ||
61 | } | ||
62 | |||
63 | static int __hw_addr_del(struct netdev_hw_addr_list *list, unsigned char *addr, | ||
64 | int addr_len, unsigned char addr_type) | ||
65 | { | ||
66 | struct netdev_hw_addr *ha; | ||
67 | |||
68 | list_for_each_entry(ha, &list->list, list) { | ||
69 | if (!memcmp(ha->addr, addr, addr_len) && | ||
70 | (ha->type == addr_type || !addr_type)) { | ||
71 | if (--ha->refcount) | ||
72 | return 0; | ||
73 | list_del_rcu(&ha->list); | ||
74 | call_rcu(&ha->rcu_head, ha_rcu_free); | ||
75 | list->count--; | ||
76 | return 0; | ||
77 | } | ||
78 | } | ||
79 | return -ENOENT; | ||
80 | } | ||
81 | |||
82 | static int __hw_addr_add_multiple(struct netdev_hw_addr_list *to_list, | ||
83 | struct netdev_hw_addr_list *from_list, | ||
84 | int addr_len, | ||
85 | unsigned char addr_type) | ||
86 | { | ||
87 | int err; | ||
88 | struct netdev_hw_addr *ha, *ha2; | ||
89 | unsigned char type; | ||
90 | |||
91 | list_for_each_entry(ha, &from_list->list, list) { | ||
92 | type = addr_type ? addr_type : ha->type; | ||
93 | err = __hw_addr_add(to_list, ha->addr, addr_len, type); | ||
94 | if (err) | ||
95 | goto unroll; | ||
96 | } | ||
97 | return 0; | ||
98 | |||
99 | unroll: | ||
100 | list_for_each_entry(ha2, &from_list->list, list) { | ||
101 | if (ha2 == ha) | ||
102 | break; | ||
103 | type = addr_type ? addr_type : ha2->type; | ||
104 | __hw_addr_del(to_list, ha2->addr, addr_len, type); | ||
105 | } | ||
106 | return err; | ||
107 | } | ||
108 | |||
109 | static void __hw_addr_del_multiple(struct netdev_hw_addr_list *to_list, | ||
110 | struct netdev_hw_addr_list *from_list, | ||
111 | int addr_len, | ||
112 | unsigned char addr_type) | ||
113 | { | ||
114 | struct netdev_hw_addr *ha; | ||
115 | unsigned char type; | ||
116 | |||
117 | list_for_each_entry(ha, &from_list->list, list) { | ||
118 | type = addr_type ? addr_type : ha->type; | ||
119 | __hw_addr_del(to_list, ha->addr, addr_len, addr_type); | ||
120 | } | ||
121 | } | ||
122 | |||
123 | static int __hw_addr_sync(struct netdev_hw_addr_list *to_list, | ||
124 | struct netdev_hw_addr_list *from_list, | ||
125 | int addr_len) | ||
126 | { | ||
127 | int err = 0; | ||
128 | struct netdev_hw_addr *ha, *tmp; | ||
129 | |||
130 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { | ||
131 | if (!ha->synced) { | ||
132 | err = __hw_addr_add(to_list, ha->addr, | ||
133 | addr_len, ha->type); | ||
134 | if (err) | ||
135 | break; | ||
136 | ha->synced = true; | ||
137 | ha->refcount++; | ||
138 | } else if (ha->refcount == 1) { | ||
139 | __hw_addr_del(to_list, ha->addr, addr_len, ha->type); | ||
140 | __hw_addr_del(from_list, ha->addr, addr_len, ha->type); | ||
141 | } | ||
142 | } | ||
143 | return err; | ||
144 | } | ||
145 | |||
146 | static void __hw_addr_unsync(struct netdev_hw_addr_list *to_list, | ||
147 | struct netdev_hw_addr_list *from_list, | ||
148 | int addr_len) | ||
149 | { | ||
150 | struct netdev_hw_addr *ha, *tmp; | ||
151 | |||
152 | list_for_each_entry_safe(ha, tmp, &from_list->list, list) { | ||
153 | if (ha->synced) { | ||
154 | __hw_addr_del(to_list, ha->addr, | ||
155 | addr_len, ha->type); | ||
156 | ha->synced = false; | ||
157 | __hw_addr_del(from_list, ha->addr, | ||
158 | addr_len, ha->type); | ||
159 | } | ||
160 | } | ||
161 | } | ||
162 | |||
163 | static void __hw_addr_flush(struct netdev_hw_addr_list *list) | ||
164 | { | ||
165 | struct netdev_hw_addr *ha, *tmp; | ||
166 | |||
167 | list_for_each_entry_safe(ha, tmp, &list->list, list) { | ||
168 | list_del_rcu(&ha->list); | ||
169 | call_rcu(&ha->rcu_head, ha_rcu_free); | ||
170 | } | ||
171 | list->count = 0; | ||
172 | } | ||
173 | |||
174 | static void __hw_addr_init(struct netdev_hw_addr_list *list) | ||
175 | { | ||
176 | INIT_LIST_HEAD(&list->list); | ||
177 | list->count = 0; | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * Device addresses handling functions | ||
182 | */ | ||
183 | |||
184 | /** | ||
185 | * dev_addr_flush - Flush device address list | ||
186 | * @dev: device | ||
187 | * | ||
188 | * Flush device address list and reset ->dev_addr. | ||
189 | * | ||
190 | * The caller must hold the rtnl_mutex. | ||
191 | */ | ||
192 | void dev_addr_flush(struct net_device *dev) | ||
193 | { | ||
194 | /* rtnl_mutex must be held here */ | ||
195 | |||
196 | __hw_addr_flush(&dev->dev_addrs); | ||
197 | dev->dev_addr = NULL; | ||
198 | } | ||
199 | EXPORT_SYMBOL(dev_addr_flush); | ||
200 | |||
201 | /** | ||
202 | * dev_addr_init - Init device address list | ||
203 | * @dev: device | ||
204 | * | ||
205 | * Init device address list and create the first element, | ||
206 | * used by ->dev_addr. | ||
207 | * | ||
208 | * The caller must hold the rtnl_mutex. | ||
209 | */ | ||
210 | int dev_addr_init(struct net_device *dev) | ||
211 | { | ||
212 | unsigned char addr[MAX_ADDR_LEN]; | ||
213 | struct netdev_hw_addr *ha; | ||
214 | int err; | ||
215 | |||
216 | /* rtnl_mutex must be held here */ | ||
217 | |||
218 | __hw_addr_init(&dev->dev_addrs); | ||
219 | memset(addr, 0, sizeof(addr)); | ||
220 | err = __hw_addr_add(&dev->dev_addrs, addr, sizeof(addr), | ||
221 | NETDEV_HW_ADDR_T_LAN); | ||
222 | if (!err) { | ||
223 | /* | ||
224 | * Get the first (previously created) address from the list | ||
225 | * and set dev_addr pointer to this location. | ||
226 | */ | ||
227 | ha = list_first_entry(&dev->dev_addrs.list, | ||
228 | struct netdev_hw_addr, list); | ||
229 | dev->dev_addr = ha->addr; | ||
230 | } | ||
231 | return err; | ||
232 | } | ||
233 | EXPORT_SYMBOL(dev_addr_init); | ||
234 | |||
235 | /** | ||
236 | * dev_addr_add - Add a device address | ||
237 | * @dev: device | ||
238 | * @addr: address to add | ||
239 | * @addr_type: address type | ||
240 | * | ||
241 | * Add a device address to the device or increase the reference count if | ||
242 | * it already exists. | ||
243 | * | ||
244 | * The caller must hold the rtnl_mutex. | ||
245 | */ | ||
246 | int dev_addr_add(struct net_device *dev, unsigned char *addr, | ||
247 | unsigned char addr_type) | ||
248 | { | ||
249 | int err; | ||
250 | |||
251 | ASSERT_RTNL(); | ||
252 | |||
253 | err = __hw_addr_add(&dev->dev_addrs, addr, dev->addr_len, addr_type); | ||
254 | if (!err) | ||
255 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | ||
256 | return err; | ||
257 | } | ||
258 | EXPORT_SYMBOL(dev_addr_add); | ||
259 | |||
260 | /** | ||
261 | * dev_addr_del - Release a device address. | ||
262 | * @dev: device | ||
263 | * @addr: address to delete | ||
264 | * @addr_type: address type | ||
265 | * | ||
266 | * Release reference to a device address and remove it from the device | ||
267 | * if the reference count drops to zero. | ||
268 | * | ||
269 | * The caller must hold the rtnl_mutex. | ||
270 | */ | ||
271 | int dev_addr_del(struct net_device *dev, unsigned char *addr, | ||
272 | unsigned char addr_type) | ||
273 | { | ||
274 | int err; | ||
275 | struct netdev_hw_addr *ha; | ||
276 | |||
277 | ASSERT_RTNL(); | ||
278 | |||
279 | /* | ||
280 | * We can not remove the first address from the list because | ||
281 | * dev->dev_addr points to that. | ||
282 | */ | ||
283 | ha = list_first_entry(&dev->dev_addrs.list, | ||
284 | struct netdev_hw_addr, list); | ||
285 | if (ha->addr == dev->dev_addr && ha->refcount == 1) | ||
286 | return -ENOENT; | ||
287 | |||
288 | err = __hw_addr_del(&dev->dev_addrs, addr, dev->addr_len, | ||
289 | addr_type); | ||
290 | if (!err) | ||
291 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | ||
292 | return err; | ||
293 | } | ||
294 | EXPORT_SYMBOL(dev_addr_del); | ||
295 | |||
296 | /** | ||
297 | * dev_addr_add_multiple - Add device addresses from another device | ||
298 | * @to_dev: device to which addresses will be added | ||
299 | * @from_dev: device from which addresses will be added | ||
300 | * @addr_type: address type - 0 means type will be used from from_dev | ||
301 | * | ||
302 | * Add device addresses of the one device to another. | ||
303 | ** | ||
304 | * The caller must hold the rtnl_mutex. | ||
305 | */ | ||
306 | int dev_addr_add_multiple(struct net_device *to_dev, | ||
307 | struct net_device *from_dev, | ||
308 | unsigned char addr_type) | ||
309 | { | ||
310 | int err; | ||
311 | |||
312 | ASSERT_RTNL(); | ||
313 | |||
314 | if (from_dev->addr_len != to_dev->addr_len) | ||
315 | return -EINVAL; | ||
316 | err = __hw_addr_add_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, | ||
317 | to_dev->addr_len, addr_type); | ||
318 | if (!err) | ||
319 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | ||
320 | return err; | ||
321 | } | ||
322 | EXPORT_SYMBOL(dev_addr_add_multiple); | ||
323 | |||
324 | /** | ||
325 | * dev_addr_del_multiple - Delete device addresses by another device | ||
326 | * @to_dev: device where the addresses will be deleted | ||
327 | * @from_dev: device by which addresses the addresses will be deleted | ||
328 | * @addr_type: address type - 0 means type will used from from_dev | ||
329 | * | ||
330 | * Deletes addresses in to device by the list of addresses in from device. | ||
331 | * | ||
332 | * The caller must hold the rtnl_mutex. | ||
333 | */ | ||
334 | int dev_addr_del_multiple(struct net_device *to_dev, | ||
335 | struct net_device *from_dev, | ||
336 | unsigned char addr_type) | ||
337 | { | ||
338 | ASSERT_RTNL(); | ||
339 | |||
340 | if (from_dev->addr_len != to_dev->addr_len) | ||
341 | return -EINVAL; | ||
342 | __hw_addr_del_multiple(&to_dev->dev_addrs, &from_dev->dev_addrs, | ||
343 | to_dev->addr_len, addr_type); | ||
344 | call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev); | ||
345 | return 0; | ||
346 | } | ||
347 | EXPORT_SYMBOL(dev_addr_del_multiple); | ||
348 | |||
349 | /* | ||
350 | * Unicast list handling functions | ||
351 | */ | ||
352 | |||
353 | /** | ||
354 | * dev_uc_add - Add a secondary unicast address | ||
355 | * @dev: device | ||
356 | * @addr: address to add | ||
357 | * | ||
358 | * Add a secondary unicast address to the device or increase | ||
359 | * the reference count if it already exists. | ||
360 | */ | ||
361 | int dev_uc_add(struct net_device *dev, unsigned char *addr) | ||
362 | { | ||
363 | int err; | ||
364 | |||
365 | netif_addr_lock_bh(dev); | ||
366 | err = __hw_addr_add(&dev->uc, addr, dev->addr_len, | ||
367 | NETDEV_HW_ADDR_T_UNICAST); | ||
368 | if (!err) | ||
369 | __dev_set_rx_mode(dev); | ||
370 | netif_addr_unlock_bh(dev); | ||
371 | return err; | ||
372 | } | ||
373 | EXPORT_SYMBOL(dev_uc_add); | ||
374 | |||
375 | /** | ||
376 | * dev_uc_del - Release secondary unicast address. | ||
377 | * @dev: device | ||
378 | * @addr: address to delete | ||
379 | * | ||
380 | * Release reference to a secondary unicast address and remove it | ||
381 | * from the device if the reference count drops to zero. | ||
382 | */ | ||
383 | int dev_uc_del(struct net_device *dev, unsigned char *addr) | ||
384 | { | ||
385 | int err; | ||
386 | |||
387 | netif_addr_lock_bh(dev); | ||
388 | err = __hw_addr_del(&dev->uc, addr, dev->addr_len, | ||
389 | NETDEV_HW_ADDR_T_UNICAST); | ||
390 | if (!err) | ||
391 | __dev_set_rx_mode(dev); | ||
392 | netif_addr_unlock_bh(dev); | ||
393 | return err; | ||
394 | } | ||
395 | EXPORT_SYMBOL(dev_uc_del); | ||
396 | |||
397 | /** | ||
398 | * dev_uc_sync - Synchronize device's unicast list to another device | ||
399 | * @to: destination device | ||
400 | * @from: source device | ||
401 | * | ||
402 | * Add newly added addresses to the destination device and release | ||
403 | * addresses that have no users left. The source device must be | ||
404 | * locked by netif_tx_lock_bh. | ||
405 | * | ||
406 | * This function is intended to be called from the dev->set_rx_mode | ||
407 | * function of layered software devices. | ||
408 | */ | ||
409 | int dev_uc_sync(struct net_device *to, struct net_device *from) | ||
410 | { | ||
411 | int err = 0; | ||
412 | |||
413 | if (to->addr_len != from->addr_len) | ||
414 | return -EINVAL; | ||
415 | |||
416 | netif_addr_lock_bh(to); | ||
417 | err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len); | ||
418 | if (!err) | ||
419 | __dev_set_rx_mode(to); | ||
420 | netif_addr_unlock_bh(to); | ||
421 | return err; | ||
422 | } | ||
423 | EXPORT_SYMBOL(dev_uc_sync); | ||
424 | |||
425 | /** | ||
426 | * dev_uc_unsync - Remove synchronized addresses from the destination device | ||
427 | * @to: destination device | ||
428 | * @from: source device | ||
429 | * | ||
430 | * Remove all addresses that were added to the destination device by | ||
431 | * dev_uc_sync(). This function is intended to be called from the | ||
432 | * dev->stop function of layered software devices. | ||
433 | */ | ||
434 | void dev_uc_unsync(struct net_device *to, struct net_device *from) | ||
435 | { | ||
436 | if (to->addr_len != from->addr_len) | ||
437 | return; | ||
438 | |||
439 | netif_addr_lock_bh(from); | ||
440 | netif_addr_lock(to); | ||
441 | __hw_addr_unsync(&to->uc, &from->uc, to->addr_len); | ||
442 | __dev_set_rx_mode(to); | ||
443 | netif_addr_unlock(to); | ||
444 | netif_addr_unlock_bh(from); | ||
445 | } | ||
446 | EXPORT_SYMBOL(dev_uc_unsync); | ||
447 | |||
448 | /** | ||
449 | * dev_uc_flush - Flush unicast addresses | ||
450 | * @dev: device | ||
451 | * | ||
452 | * Flush unicast addresses. | ||
453 | */ | ||
454 | void dev_uc_flush(struct net_device *dev) | ||
455 | { | ||
456 | netif_addr_lock_bh(dev); | ||
457 | __hw_addr_flush(&dev->uc); | ||
458 | netif_addr_unlock_bh(dev); | ||
459 | } | ||
460 | EXPORT_SYMBOL(dev_uc_flush); | ||
461 | |||
462 | /** | ||
463 | * dev_uc_flush - Init unicast address list | ||
464 | * @dev: device | ||
465 | * | ||
466 | * Init unicast address list. | ||
467 | */ | ||
468 | void dev_uc_init(struct net_device *dev) | ||
469 | { | ||
470 | __hw_addr_init(&dev->uc); | ||
471 | } | ||
472 | EXPORT_SYMBOL(dev_uc_init); | ||
473 | |||
474 | /* | ||
475 | * Multicast list handling functions | ||
476 | */ | ||
477 | |||
478 | /* To be filled here */ | ||
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 2175e6d5cc8d..8fdca56bb08f 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c | |||
@@ -67,7 +67,7 @@ static int dsa_slave_open(struct net_device *dev) | |||
67 | return -ENETDOWN; | 67 | return -ENETDOWN; |
68 | 68 | ||
69 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) { | 69 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) { |
70 | err = dev_unicast_add(master, dev->dev_addr); | 70 | err = dev_uc_add(master, dev->dev_addr); |
71 | if (err < 0) | 71 | if (err < 0) |
72 | goto out; | 72 | goto out; |
73 | } | 73 | } |
@@ -90,7 +90,7 @@ clear_allmulti: | |||
90 | dev_set_allmulti(master, -1); | 90 | dev_set_allmulti(master, -1); |
91 | del_unicast: | 91 | del_unicast: |
92 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) | 92 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) |
93 | dev_unicast_delete(master, dev->dev_addr); | 93 | dev_uc_del(master, dev->dev_addr); |
94 | out: | 94 | out: |
95 | return err; | 95 | return err; |
96 | } | 96 | } |
@@ -101,14 +101,14 @@ static int dsa_slave_close(struct net_device *dev) | |||
101 | struct net_device *master = p->parent->dst->master_netdev; | 101 | struct net_device *master = p->parent->dst->master_netdev; |
102 | 102 | ||
103 | dev_mc_unsync(master, dev); | 103 | dev_mc_unsync(master, dev); |
104 | dev_unicast_unsync(master, dev); | 104 | dev_uc_unsync(master, dev); |
105 | if (dev->flags & IFF_ALLMULTI) | 105 | if (dev->flags & IFF_ALLMULTI) |
106 | dev_set_allmulti(master, -1); | 106 | dev_set_allmulti(master, -1); |
107 | if (dev->flags & IFF_PROMISC) | 107 | if (dev->flags & IFF_PROMISC) |
108 | dev_set_promiscuity(master, -1); | 108 | dev_set_promiscuity(master, -1); |
109 | 109 | ||
110 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) | 110 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) |
111 | dev_unicast_delete(master, dev->dev_addr); | 111 | dev_uc_del(master, dev->dev_addr); |
112 | 112 | ||
113 | return 0; | 113 | return 0; |
114 | } | 114 | } |
@@ -130,7 +130,7 @@ static void dsa_slave_set_rx_mode(struct net_device *dev) | |||
130 | struct net_device *master = p->parent->dst->master_netdev; | 130 | struct net_device *master = p->parent->dst->master_netdev; |
131 | 131 | ||
132 | dev_mc_sync(master, dev); | 132 | dev_mc_sync(master, dev); |
133 | dev_unicast_sync(master, dev); | 133 | dev_uc_sync(master, dev); |
134 | } | 134 | } |
135 | 135 | ||
136 | static int dsa_slave_set_mac_address(struct net_device *dev, void *a) | 136 | static int dsa_slave_set_mac_address(struct net_device *dev, void *a) |
@@ -147,13 +147,13 @@ static int dsa_slave_set_mac_address(struct net_device *dev, void *a) | |||
147 | goto out; | 147 | goto out; |
148 | 148 | ||
149 | if (compare_ether_addr(addr->sa_data, master->dev_addr)) { | 149 | if (compare_ether_addr(addr->sa_data, master->dev_addr)) { |
150 | err = dev_unicast_add(master, addr->sa_data); | 150 | err = dev_uc_add(master, addr->sa_data); |
151 | if (err < 0) | 151 | if (err < 0) |
152 | return err; | 152 | return err; |
153 | } | 153 | } |
154 | 154 | ||
155 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) | 155 | if (compare_ether_addr(dev->dev_addr, master->dev_addr)) |
156 | dev_unicast_delete(master, dev->dev_addr); | 156 | dev_uc_del(master, dev->dev_addr); |
157 | 157 | ||
158 | out: | 158 | out: |
159 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | 159 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 1612d417d10c..48c1e0ae565f 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -1705,9 +1705,9 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, | |||
1705 | if (i->alen != dev->addr_len) | 1705 | if (i->alen != dev->addr_len) |
1706 | return -EINVAL; | 1706 | return -EINVAL; |
1707 | if (what > 0) | 1707 | if (what > 0) |
1708 | return dev_unicast_add(dev, i->addr); | 1708 | return dev_uc_add(dev, i->addr); |
1709 | else | 1709 | else |
1710 | return dev_unicast_delete(dev, i->addr); | 1710 | return dev_uc_del(dev, i->addr); |
1711 | break; | 1711 | break; |
1712 | default: | 1712 | default: |
1713 | break; | 1713 | break; |