diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 430 |
1 files changed, 3 insertions, 427 deletions
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); |