diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 500 | ||||
-rw-r--r-- | net/core/flow_dissector.c | 39 | ||||
-rw-r--r-- | net/core/neighbour.c | 2 | ||||
-rw-r--r-- | net/core/netprio_cgroup.c | 3 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 3 | ||||
-rw-r--r-- | net/core/sock.c | 12 |
6 files changed, 386 insertions, 173 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 3430b1ed12e5..1b6eadf69289 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1307,7 +1307,7 @@ static int __dev_close_many(struct list_head *head) | |||
1307 | ASSERT_RTNL(); | 1307 | ASSERT_RTNL(); |
1308 | might_sleep(); | 1308 | might_sleep(); |
1309 | 1309 | ||
1310 | list_for_each_entry(dev, head, unreg_list) { | 1310 | list_for_each_entry(dev, head, close_list) { |
1311 | call_netdevice_notifiers(NETDEV_GOING_DOWN, dev); | 1311 | call_netdevice_notifiers(NETDEV_GOING_DOWN, dev); |
1312 | 1312 | ||
1313 | clear_bit(__LINK_STATE_START, &dev->state); | 1313 | clear_bit(__LINK_STATE_START, &dev->state); |
@@ -1323,7 +1323,7 @@ static int __dev_close_many(struct list_head *head) | |||
1323 | 1323 | ||
1324 | dev_deactivate_many(head); | 1324 | dev_deactivate_many(head); |
1325 | 1325 | ||
1326 | list_for_each_entry(dev, head, unreg_list) { | 1326 | list_for_each_entry(dev, head, close_list) { |
1327 | const struct net_device_ops *ops = dev->netdev_ops; | 1327 | const struct net_device_ops *ops = dev->netdev_ops; |
1328 | 1328 | ||
1329 | /* | 1329 | /* |
@@ -1351,7 +1351,7 @@ static int __dev_close(struct net_device *dev) | |||
1351 | /* Temporarily disable netpoll until the interface is down */ | 1351 | /* Temporarily disable netpoll until the interface is down */ |
1352 | netpoll_rx_disable(dev); | 1352 | netpoll_rx_disable(dev); |
1353 | 1353 | ||
1354 | list_add(&dev->unreg_list, &single); | 1354 | list_add(&dev->close_list, &single); |
1355 | retval = __dev_close_many(&single); | 1355 | retval = __dev_close_many(&single); |
1356 | list_del(&single); | 1356 | list_del(&single); |
1357 | 1357 | ||
@@ -1362,21 +1362,20 @@ static int __dev_close(struct net_device *dev) | |||
1362 | static int dev_close_many(struct list_head *head) | 1362 | static int dev_close_many(struct list_head *head) |
1363 | { | 1363 | { |
1364 | struct net_device *dev, *tmp; | 1364 | struct net_device *dev, *tmp; |
1365 | LIST_HEAD(tmp_list); | ||
1366 | 1365 | ||
1367 | list_for_each_entry_safe(dev, tmp, head, unreg_list) | 1366 | /* Remove the devices that don't need to be closed */ |
1367 | list_for_each_entry_safe(dev, tmp, head, close_list) | ||
1368 | if (!(dev->flags & IFF_UP)) | 1368 | if (!(dev->flags & IFF_UP)) |
1369 | list_move(&dev->unreg_list, &tmp_list); | 1369 | list_del_init(&dev->close_list); |
1370 | 1370 | ||
1371 | __dev_close_many(head); | 1371 | __dev_close_many(head); |
1372 | 1372 | ||
1373 | list_for_each_entry(dev, head, unreg_list) { | 1373 | list_for_each_entry_safe(dev, tmp, head, close_list) { |
1374 | rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); | 1374 | rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); |
1375 | call_netdevice_notifiers(NETDEV_DOWN, dev); | 1375 | call_netdevice_notifiers(NETDEV_DOWN, dev); |
1376 | list_del_init(&dev->close_list); | ||
1376 | } | 1377 | } |
1377 | 1378 | ||
1378 | /* rollback_registered_many needs the complete original list */ | ||
1379 | list_splice(&tmp_list, head); | ||
1380 | return 0; | 1379 | return 0; |
1381 | } | 1380 | } |
1382 | 1381 | ||
@@ -1397,7 +1396,7 @@ int dev_close(struct net_device *dev) | |||
1397 | /* Block netpoll rx while the interface is going down */ | 1396 | /* Block netpoll rx while the interface is going down */ |
1398 | netpoll_rx_disable(dev); | 1397 | netpoll_rx_disable(dev); |
1399 | 1398 | ||
1400 | list_add(&dev->unreg_list, &single); | 1399 | list_add(&dev->close_list, &single); |
1401 | dev_close_many(&single); | 1400 | dev_close_many(&single); |
1402 | list_del(&single); | 1401 | list_del(&single); |
1403 | 1402 | ||
@@ -4374,42 +4373,40 @@ struct netdev_adjacent { | |||
4374 | /* upper master flag, there can only be one master device per list */ | 4373 | /* upper master flag, there can only be one master device per list */ |
4375 | bool master; | 4374 | bool master; |
4376 | 4375 | ||
4377 | /* indicates that this dev is our first-level lower/upper device */ | ||
4378 | bool neighbour; | ||
4379 | |||
4380 | /* counter for the number of times this device was added to us */ | 4376 | /* counter for the number of times this device was added to us */ |
4381 | u16 ref_nr; | 4377 | u16 ref_nr; |
4382 | 4378 | ||
4379 | /* private field for the users */ | ||
4380 | void *private; | ||
4381 | |||
4383 | struct list_head list; | 4382 | struct list_head list; |
4384 | struct rcu_head rcu; | 4383 | struct rcu_head rcu; |
4385 | }; | 4384 | }; |
4386 | 4385 | ||
4387 | static struct netdev_adjacent *__netdev_find_adj(struct net_device *dev, | 4386 | static struct netdev_adjacent *__netdev_find_adj_rcu(struct net_device *dev, |
4388 | struct net_device *adj_dev, | 4387 | struct net_device *adj_dev, |
4389 | bool upper) | 4388 | struct list_head *adj_list) |
4390 | { | 4389 | { |
4391 | struct netdev_adjacent *adj; | 4390 | struct netdev_adjacent *adj; |
4392 | struct list_head *dev_list; | ||
4393 | 4391 | ||
4394 | dev_list = upper ? &dev->upper_dev_list : &dev->lower_dev_list; | 4392 | list_for_each_entry_rcu(adj, adj_list, list) { |
4395 | |||
4396 | list_for_each_entry(adj, dev_list, list) { | ||
4397 | if (adj->dev == adj_dev) | 4393 | if (adj->dev == adj_dev) |
4398 | return adj; | 4394 | return adj; |
4399 | } | 4395 | } |
4400 | return NULL; | 4396 | return NULL; |
4401 | } | 4397 | } |
4402 | 4398 | ||
4403 | static inline struct netdev_adjacent *__netdev_find_upper(struct net_device *dev, | 4399 | static struct netdev_adjacent *__netdev_find_adj(struct net_device *dev, |
4404 | struct net_device *udev) | 4400 | struct net_device *adj_dev, |
4401 | struct list_head *adj_list) | ||
4405 | { | 4402 | { |
4406 | return __netdev_find_adj(dev, udev, true); | 4403 | struct netdev_adjacent *adj; |
4407 | } | ||
4408 | 4404 | ||
4409 | static inline struct netdev_adjacent *__netdev_find_lower(struct net_device *dev, | 4405 | list_for_each_entry(adj, adj_list, list) { |
4410 | struct net_device *ldev) | 4406 | if (adj->dev == adj_dev) |
4411 | { | 4407 | return adj; |
4412 | return __netdev_find_adj(dev, ldev, false); | 4408 | } |
4409 | return NULL; | ||
4413 | } | 4410 | } |
4414 | 4411 | ||
4415 | /** | 4412 | /** |
@@ -4426,7 +4423,7 @@ bool netdev_has_upper_dev(struct net_device *dev, | |||
4426 | { | 4423 | { |
4427 | ASSERT_RTNL(); | 4424 | ASSERT_RTNL(); |
4428 | 4425 | ||
4429 | return __netdev_find_upper(dev, upper_dev); | 4426 | return __netdev_find_adj(dev, upper_dev, &dev->all_adj_list.upper); |
4430 | } | 4427 | } |
4431 | EXPORT_SYMBOL(netdev_has_upper_dev); | 4428 | EXPORT_SYMBOL(netdev_has_upper_dev); |
4432 | 4429 | ||
@@ -4441,7 +4438,7 @@ bool netdev_has_any_upper_dev(struct net_device *dev) | |||
4441 | { | 4438 | { |
4442 | ASSERT_RTNL(); | 4439 | ASSERT_RTNL(); |
4443 | 4440 | ||
4444 | return !list_empty(&dev->upper_dev_list); | 4441 | return !list_empty(&dev->all_adj_list.upper); |
4445 | } | 4442 | } |
4446 | EXPORT_SYMBOL(netdev_has_any_upper_dev); | 4443 | EXPORT_SYMBOL(netdev_has_any_upper_dev); |
4447 | 4444 | ||
@@ -4458,10 +4455,10 @@ struct net_device *netdev_master_upper_dev_get(struct net_device *dev) | |||
4458 | 4455 | ||
4459 | ASSERT_RTNL(); | 4456 | ASSERT_RTNL(); |
4460 | 4457 | ||
4461 | if (list_empty(&dev->upper_dev_list)) | 4458 | if (list_empty(&dev->adj_list.upper)) |
4462 | return NULL; | 4459 | return NULL; |
4463 | 4460 | ||
4464 | upper = list_first_entry(&dev->upper_dev_list, | 4461 | upper = list_first_entry(&dev->adj_list.upper, |
4465 | struct netdev_adjacent, list); | 4462 | struct netdev_adjacent, list); |
4466 | if (likely(upper->master)) | 4463 | if (likely(upper->master)) |
4467 | return upper->dev; | 4464 | return upper->dev; |
@@ -4469,15 +4466,26 @@ struct net_device *netdev_master_upper_dev_get(struct net_device *dev) | |||
4469 | } | 4466 | } |
4470 | EXPORT_SYMBOL(netdev_master_upper_dev_get); | 4467 | EXPORT_SYMBOL(netdev_master_upper_dev_get); |
4471 | 4468 | ||
4472 | /* netdev_upper_get_next_dev_rcu - Get the next dev from upper list | 4469 | void *netdev_adjacent_get_private(struct list_head *adj_list) |
4470 | { | ||
4471 | struct netdev_adjacent *adj; | ||
4472 | |||
4473 | adj = list_entry(adj_list, struct netdev_adjacent, list); | ||
4474 | |||
4475 | return adj->private; | ||
4476 | } | ||
4477 | EXPORT_SYMBOL(netdev_adjacent_get_private); | ||
4478 | |||
4479 | /** | ||
4480 | * netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list | ||
4473 | * @dev: device | 4481 | * @dev: device |
4474 | * @iter: list_head ** of the current position | 4482 | * @iter: list_head ** of the current position |
4475 | * | 4483 | * |
4476 | * Gets the next device from the dev's upper list, starting from iter | 4484 | * Gets the next device from the dev's upper list, starting from iter |
4477 | * position. The caller must hold RCU read lock. | 4485 | * position. The caller must hold RCU read lock. |
4478 | */ | 4486 | */ |
4479 | struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev, | 4487 | struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev, |
4480 | struct list_head **iter) | 4488 | struct list_head **iter) |
4481 | { | 4489 | { |
4482 | struct netdev_adjacent *upper; | 4490 | struct netdev_adjacent *upper; |
4483 | 4491 | ||
@@ -4485,14 +4493,71 @@ struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev, | |||
4485 | 4493 | ||
4486 | upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list); | 4494 | upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list); |
4487 | 4495 | ||
4488 | if (&upper->list == &dev->upper_dev_list) | 4496 | if (&upper->list == &dev->all_adj_list.upper) |
4489 | return NULL; | 4497 | return NULL; |
4490 | 4498 | ||
4491 | *iter = &upper->list; | 4499 | *iter = &upper->list; |
4492 | 4500 | ||
4493 | return upper->dev; | 4501 | return upper->dev; |
4494 | } | 4502 | } |
4495 | EXPORT_SYMBOL(netdev_upper_get_next_dev_rcu); | 4503 | EXPORT_SYMBOL(netdev_all_upper_get_next_dev_rcu); |
4504 | |||
4505 | /** | ||
4506 | * netdev_lower_get_next_private - Get the next ->private from the | ||
4507 | * lower neighbour list | ||
4508 | * @dev: device | ||
4509 | * @iter: list_head ** of the current position | ||
4510 | * | ||
4511 | * Gets the next netdev_adjacent->private from the dev's lower neighbour | ||
4512 | * list, starting from iter position. The caller must hold either hold the | ||
4513 | * RTNL lock or its own locking that guarantees that the neighbour lower | ||
4514 | * list will remain unchainged. | ||
4515 | */ | ||
4516 | void *netdev_lower_get_next_private(struct net_device *dev, | ||
4517 | struct list_head **iter) | ||
4518 | { | ||
4519 | struct netdev_adjacent *lower; | ||
4520 | |||
4521 | lower = list_entry(*iter, struct netdev_adjacent, list); | ||
4522 | |||
4523 | if (&lower->list == &dev->adj_list.lower) | ||
4524 | return NULL; | ||
4525 | |||
4526 | if (iter) | ||
4527 | *iter = lower->list.next; | ||
4528 | |||
4529 | return lower->private; | ||
4530 | } | ||
4531 | EXPORT_SYMBOL(netdev_lower_get_next_private); | ||
4532 | |||
4533 | /** | ||
4534 | * netdev_lower_get_next_private_rcu - Get the next ->private from the | ||
4535 | * lower neighbour list, RCU | ||
4536 | * variant | ||
4537 | * @dev: device | ||
4538 | * @iter: list_head ** of the current position | ||
4539 | * | ||
4540 | * Gets the next netdev_adjacent->private from the dev's lower neighbour | ||
4541 | * list, starting from iter position. The caller must hold RCU read lock. | ||
4542 | */ | ||
4543 | void *netdev_lower_get_next_private_rcu(struct net_device *dev, | ||
4544 | struct list_head **iter) | ||
4545 | { | ||
4546 | struct netdev_adjacent *lower; | ||
4547 | |||
4548 | WARN_ON_ONCE(!rcu_read_lock_held()); | ||
4549 | |||
4550 | lower = list_entry_rcu((*iter)->next, struct netdev_adjacent, list); | ||
4551 | |||
4552 | if (&lower->list == &dev->adj_list.lower) | ||
4553 | return NULL; | ||
4554 | |||
4555 | if (iter) | ||
4556 | *iter = &lower->list; | ||
4557 | |||
4558 | return lower->private; | ||
4559 | } | ||
4560 | EXPORT_SYMBOL(netdev_lower_get_next_private_rcu); | ||
4496 | 4561 | ||
4497 | /** | 4562 | /** |
4498 | * netdev_master_upper_dev_get_rcu - Get master upper device | 4563 | * netdev_master_upper_dev_get_rcu - Get master upper device |
@@ -4505,7 +4570,7 @@ struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev) | |||
4505 | { | 4570 | { |
4506 | struct netdev_adjacent *upper; | 4571 | struct netdev_adjacent *upper; |
4507 | 4572 | ||
4508 | upper = list_first_or_null_rcu(&dev->upper_dev_list, | 4573 | upper = list_first_or_null_rcu(&dev->adj_list.upper, |
4509 | struct netdev_adjacent, list); | 4574 | struct netdev_adjacent, list); |
4510 | if (upper && likely(upper->master)) | 4575 | if (upper && likely(upper->master)) |
4511 | return upper->dev; | 4576 | return upper->dev; |
@@ -4515,15 +4580,16 @@ EXPORT_SYMBOL(netdev_master_upper_dev_get_rcu); | |||
4515 | 4580 | ||
4516 | static int __netdev_adjacent_dev_insert(struct net_device *dev, | 4581 | static int __netdev_adjacent_dev_insert(struct net_device *dev, |
4517 | struct net_device *adj_dev, | 4582 | struct net_device *adj_dev, |
4518 | bool neighbour, bool master, | 4583 | struct list_head *dev_list, |
4519 | bool upper) | 4584 | void *private, bool master) |
4520 | { | 4585 | { |
4521 | struct netdev_adjacent *adj; | 4586 | struct netdev_adjacent *adj; |
4587 | char linkname[IFNAMSIZ+7]; | ||
4588 | int ret; | ||
4522 | 4589 | ||
4523 | adj = __netdev_find_adj(dev, adj_dev, upper); | 4590 | adj = __netdev_find_adj(dev, adj_dev, dev_list); |
4524 | 4591 | ||
4525 | if (adj) { | 4592 | if (adj) { |
4526 | BUG_ON(neighbour); | ||
4527 | adj->ref_nr++; | 4593 | adj->ref_nr++; |
4528 | return 0; | 4594 | return 0; |
4529 | } | 4595 | } |
@@ -4534,124 +4600,178 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev, | |||
4534 | 4600 | ||
4535 | adj->dev = adj_dev; | 4601 | adj->dev = adj_dev; |
4536 | adj->master = master; | 4602 | adj->master = master; |
4537 | adj->neighbour = neighbour; | ||
4538 | adj->ref_nr = 1; | 4603 | adj->ref_nr = 1; |
4539 | 4604 | adj->private = private; | |
4540 | dev_hold(adj_dev); | 4605 | dev_hold(adj_dev); |
4541 | pr_debug("dev_hold for %s, because of %s link added from %s to %s\n", | ||
4542 | adj_dev->name, upper ? "upper" : "lower", dev->name, | ||
4543 | adj_dev->name); | ||
4544 | 4606 | ||
4545 | if (!upper) { | 4607 | pr_debug("dev_hold for %s, because of link added from %s to %s\n", |
4546 | list_add_tail_rcu(&adj->list, &dev->lower_dev_list); | 4608 | adj_dev->name, dev->name, adj_dev->name); |
4547 | return 0; | 4609 | |
4610 | if (dev_list == &dev->adj_list.lower) { | ||
4611 | sprintf(linkname, "lower_%s", adj_dev->name); | ||
4612 | ret = sysfs_create_link(&(dev->dev.kobj), | ||
4613 | &(adj_dev->dev.kobj), linkname); | ||
4614 | if (ret) | ||
4615 | goto free_adj; | ||
4616 | } else if (dev_list == &dev->adj_list.upper) { | ||
4617 | sprintf(linkname, "upper_%s", adj_dev->name); | ||
4618 | ret = sysfs_create_link(&(dev->dev.kobj), | ||
4619 | &(adj_dev->dev.kobj), linkname); | ||
4620 | if (ret) | ||
4621 | goto free_adj; | ||
4548 | } | 4622 | } |
4549 | 4623 | ||
4550 | /* Ensure that master upper link is always the first item in list. */ | 4624 | /* Ensure that master link is always the first item in list. */ |
4551 | if (master) | 4625 | if (master) { |
4552 | list_add_rcu(&adj->list, &dev->upper_dev_list); | 4626 | ret = sysfs_create_link(&(dev->dev.kobj), |
4553 | else | 4627 | &(adj_dev->dev.kobj), "master"); |
4554 | list_add_tail_rcu(&adj->list, &dev->upper_dev_list); | 4628 | if (ret) |
4629 | goto remove_symlinks; | ||
4630 | |||
4631 | list_add_rcu(&adj->list, dev_list); | ||
4632 | } else { | ||
4633 | list_add_tail_rcu(&adj->list, dev_list); | ||
4634 | } | ||
4555 | 4635 | ||
4556 | return 0; | 4636 | return 0; |
4557 | } | ||
4558 | 4637 | ||
4559 | static inline int __netdev_upper_dev_insert(struct net_device *dev, | 4638 | remove_symlinks: |
4560 | struct net_device *udev, | 4639 | if (dev_list == &dev->adj_list.lower) { |
4561 | bool master, bool neighbour) | 4640 | sprintf(linkname, "lower_%s", adj_dev->name); |
4562 | { | 4641 | sysfs_remove_link(&(dev->dev.kobj), linkname); |
4563 | return __netdev_adjacent_dev_insert(dev, udev, neighbour, master, | 4642 | } else if (dev_list == &dev->adj_list.upper) { |
4564 | true); | 4643 | sprintf(linkname, "upper_%s", adj_dev->name); |
4565 | } | 4644 | sysfs_remove_link(&(dev->dev.kobj), linkname); |
4645 | } | ||
4566 | 4646 | ||
4567 | static inline int __netdev_lower_dev_insert(struct net_device *dev, | 4647 | free_adj: |
4568 | struct net_device *ldev, | 4648 | kfree(adj); |
4569 | bool neighbour) | 4649 | |
4570 | { | 4650 | return ret; |
4571 | return __netdev_adjacent_dev_insert(dev, ldev, neighbour, false, | ||
4572 | false); | ||
4573 | } | 4651 | } |
4574 | 4652 | ||
4575 | void __netdev_adjacent_dev_remove(struct net_device *dev, | 4653 | void __netdev_adjacent_dev_remove(struct net_device *dev, |
4576 | struct net_device *adj_dev, bool upper) | 4654 | struct net_device *adj_dev, |
4655 | struct list_head *dev_list) | ||
4577 | { | 4656 | { |
4578 | struct netdev_adjacent *adj; | 4657 | struct netdev_adjacent *adj; |
4658 | char linkname[IFNAMSIZ+7]; | ||
4579 | 4659 | ||
4580 | if (upper) | 4660 | adj = __netdev_find_adj(dev, adj_dev, dev_list); |
4581 | adj = __netdev_find_upper(dev, adj_dev); | ||
4582 | else | ||
4583 | adj = __netdev_find_lower(dev, adj_dev); | ||
4584 | 4661 | ||
4585 | if (!adj) | 4662 | if (!adj) { |
4663 | pr_err("tried to remove device %s from %s\n", | ||
4664 | dev->name, adj_dev->name); | ||
4586 | BUG(); | 4665 | BUG(); |
4666 | } | ||
4587 | 4667 | ||
4588 | if (adj->ref_nr > 1) { | 4668 | if (adj->ref_nr > 1) { |
4669 | pr_debug("%s to %s ref_nr-- = %d\n", dev->name, adj_dev->name, | ||
4670 | adj->ref_nr-1); | ||
4589 | adj->ref_nr--; | 4671 | adj->ref_nr--; |
4590 | return; | 4672 | return; |
4591 | } | 4673 | } |
4592 | 4674 | ||
4675 | if (adj->master) | ||
4676 | sysfs_remove_link(&(dev->dev.kobj), "master"); | ||
4677 | |||
4678 | if (dev_list == &dev->adj_list.lower) { | ||
4679 | sprintf(linkname, "lower_%s", adj_dev->name); | ||
4680 | sysfs_remove_link(&(dev->dev.kobj), linkname); | ||
4681 | } else if (dev_list == &dev->adj_list.upper) { | ||
4682 | sprintf(linkname, "upper_%s", adj_dev->name); | ||
4683 | sysfs_remove_link(&(dev->dev.kobj), linkname); | ||
4684 | } | ||
4685 | |||
4593 | list_del_rcu(&adj->list); | 4686 | list_del_rcu(&adj->list); |
4594 | pr_debug("dev_put for %s, because of %s link removed from %s to %s\n", | 4687 | pr_debug("dev_put for %s, because link removed from %s to %s\n", |
4595 | adj_dev->name, upper ? "upper" : "lower", dev->name, | 4688 | adj_dev->name, dev->name, adj_dev->name); |
4596 | adj_dev->name); | ||
4597 | dev_put(adj_dev); | 4689 | dev_put(adj_dev); |
4598 | kfree_rcu(adj, rcu); | 4690 | kfree_rcu(adj, rcu); |
4599 | } | 4691 | } |
4600 | 4692 | ||
4601 | static inline void __netdev_upper_dev_remove(struct net_device *dev, | 4693 | int __netdev_adjacent_dev_link_lists(struct net_device *dev, |
4602 | struct net_device *udev) | 4694 | struct net_device *upper_dev, |
4603 | { | 4695 | struct list_head *up_list, |
4604 | return __netdev_adjacent_dev_remove(dev, udev, true); | 4696 | struct list_head *down_list, |
4605 | } | 4697 | void *private, bool master) |
4606 | |||
4607 | static inline void __netdev_lower_dev_remove(struct net_device *dev, | ||
4608 | struct net_device *ldev) | ||
4609 | { | ||
4610 | return __netdev_adjacent_dev_remove(dev, ldev, false); | ||
4611 | } | ||
4612 | |||
4613 | int __netdev_adjacent_dev_insert_link(struct net_device *dev, | ||
4614 | struct net_device *upper_dev, | ||
4615 | bool master, bool neighbour) | ||
4616 | { | 4698 | { |
4617 | int ret; | 4699 | int ret; |
4618 | 4700 | ||
4619 | ret = __netdev_upper_dev_insert(dev, upper_dev, master, neighbour); | 4701 | ret = __netdev_adjacent_dev_insert(dev, upper_dev, up_list, private, |
4702 | master); | ||
4620 | if (ret) | 4703 | if (ret) |
4621 | return ret; | 4704 | return ret; |
4622 | 4705 | ||
4623 | ret = __netdev_lower_dev_insert(upper_dev, dev, neighbour); | 4706 | ret = __netdev_adjacent_dev_insert(upper_dev, dev, down_list, private, |
4707 | false); | ||
4624 | if (ret) { | 4708 | if (ret) { |
4625 | __netdev_upper_dev_remove(dev, upper_dev); | 4709 | __netdev_adjacent_dev_remove(dev, upper_dev, up_list); |
4626 | return ret; | 4710 | return ret; |
4627 | } | 4711 | } |
4628 | 4712 | ||
4629 | return 0; | 4713 | return 0; |
4630 | } | 4714 | } |
4631 | 4715 | ||
4632 | static inline int __netdev_adjacent_dev_link(struct net_device *dev, | 4716 | int __netdev_adjacent_dev_link(struct net_device *dev, |
4633 | struct net_device *udev) | 4717 | struct net_device *upper_dev) |
4634 | { | 4718 | { |
4635 | return __netdev_adjacent_dev_insert_link(dev, udev, false, false); | 4719 | return __netdev_adjacent_dev_link_lists(dev, upper_dev, |
4720 | &dev->all_adj_list.upper, | ||
4721 | &upper_dev->all_adj_list.lower, | ||
4722 | NULL, false); | ||
4636 | } | 4723 | } |
4637 | 4724 | ||
4638 | static inline int __netdev_adjacent_dev_link_neighbour(struct net_device *dev, | 4725 | void __netdev_adjacent_dev_unlink_lists(struct net_device *dev, |
4639 | struct net_device *udev, | 4726 | struct net_device *upper_dev, |
4640 | bool master) | 4727 | struct list_head *up_list, |
4728 | struct list_head *down_list) | ||
4641 | { | 4729 | { |
4642 | return __netdev_adjacent_dev_insert_link(dev, udev, master, true); | 4730 | __netdev_adjacent_dev_remove(dev, upper_dev, up_list); |
4731 | __netdev_adjacent_dev_remove(upper_dev, dev, down_list); | ||
4643 | } | 4732 | } |
4644 | 4733 | ||
4645 | void __netdev_adjacent_dev_unlink(struct net_device *dev, | 4734 | void __netdev_adjacent_dev_unlink(struct net_device *dev, |
4646 | struct net_device *upper_dev) | 4735 | struct net_device *upper_dev) |
4647 | { | 4736 | { |
4648 | __netdev_upper_dev_remove(dev, upper_dev); | 4737 | __netdev_adjacent_dev_unlink_lists(dev, upper_dev, |
4649 | __netdev_lower_dev_remove(upper_dev, dev); | 4738 | &dev->all_adj_list.upper, |
4739 | &upper_dev->all_adj_list.lower); | ||
4650 | } | 4740 | } |
4651 | 4741 | ||
4742 | int __netdev_adjacent_dev_link_neighbour(struct net_device *dev, | ||
4743 | struct net_device *upper_dev, | ||
4744 | void *private, bool master) | ||
4745 | { | ||
4746 | int ret = __netdev_adjacent_dev_link(dev, upper_dev); | ||
4747 | |||
4748 | if (ret) | ||
4749 | return ret; | ||
4750 | |||
4751 | ret = __netdev_adjacent_dev_link_lists(dev, upper_dev, | ||
4752 | &dev->adj_list.upper, | ||
4753 | &upper_dev->adj_list.lower, | ||
4754 | private, master); | ||
4755 | if (ret) { | ||
4756 | __netdev_adjacent_dev_unlink(dev, upper_dev); | ||
4757 | return ret; | ||
4758 | } | ||
4759 | |||
4760 | return 0; | ||
4761 | } | ||
4762 | |||
4763 | void __netdev_adjacent_dev_unlink_neighbour(struct net_device *dev, | ||
4764 | struct net_device *upper_dev) | ||
4765 | { | ||
4766 | __netdev_adjacent_dev_unlink(dev, upper_dev); | ||
4767 | __netdev_adjacent_dev_unlink_lists(dev, upper_dev, | ||
4768 | &dev->adj_list.upper, | ||
4769 | &upper_dev->adj_list.lower); | ||
4770 | } | ||
4652 | 4771 | ||
4653 | static int __netdev_upper_dev_link(struct net_device *dev, | 4772 | static int __netdev_upper_dev_link(struct net_device *dev, |
4654 | struct net_device *upper_dev, bool master) | 4773 | struct net_device *upper_dev, bool master, |
4774 | void *private) | ||
4655 | { | 4775 | { |
4656 | struct netdev_adjacent *i, *j, *to_i, *to_j; | 4776 | struct netdev_adjacent *i, *j, *to_i, *to_j; |
4657 | int ret = 0; | 4777 | int ret = 0; |
@@ -4662,26 +4782,29 @@ static int __netdev_upper_dev_link(struct net_device *dev, | |||
4662 | return -EBUSY; | 4782 | return -EBUSY; |
4663 | 4783 | ||
4664 | /* To prevent loops, check if dev is not upper device to upper_dev. */ | 4784 | /* To prevent loops, check if dev is not upper device to upper_dev. */ |
4665 | if (__netdev_find_upper(upper_dev, dev)) | 4785 | if (__netdev_find_adj(upper_dev, dev, &upper_dev->all_adj_list.upper)) |
4666 | return -EBUSY; | 4786 | return -EBUSY; |
4667 | 4787 | ||
4668 | if (__netdev_find_upper(dev, upper_dev)) | 4788 | if (__netdev_find_adj(dev, upper_dev, &dev->all_adj_list.upper)) |
4669 | return -EEXIST; | 4789 | return -EEXIST; |
4670 | 4790 | ||
4671 | if (master && netdev_master_upper_dev_get(dev)) | 4791 | if (master && netdev_master_upper_dev_get(dev)) |
4672 | return -EBUSY; | 4792 | return -EBUSY; |
4673 | 4793 | ||
4674 | ret = __netdev_adjacent_dev_link_neighbour(dev, upper_dev, master); | 4794 | ret = __netdev_adjacent_dev_link_neighbour(dev, upper_dev, private, |
4795 | master); | ||
4675 | if (ret) | 4796 | if (ret) |
4676 | return ret; | 4797 | return ret; |
4677 | 4798 | ||
4678 | /* Now that we linked these devs, make all the upper_dev's | 4799 | /* Now that we linked these devs, make all the upper_dev's |
4679 | * upper_dev_list visible to every dev's lower_dev_list and vice | 4800 | * all_adj_list.upper visible to every dev's all_adj_list.lower an |
4680 | * versa, and don't forget the devices itself. All of these | 4801 | * versa, and don't forget the devices itself. All of these |
4681 | * links are non-neighbours. | 4802 | * links are non-neighbours. |
4682 | */ | 4803 | */ |
4683 | list_for_each_entry(i, &dev->lower_dev_list, list) { | 4804 | list_for_each_entry(i, &dev->all_adj_list.lower, list) { |
4684 | list_for_each_entry(j, &upper_dev->upper_dev_list, list) { | 4805 | list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) { |
4806 | pr_debug("Interlinking %s with %s, non-neighbour\n", | ||
4807 | i->dev->name, j->dev->name); | ||
4685 | ret = __netdev_adjacent_dev_link(i->dev, j->dev); | 4808 | ret = __netdev_adjacent_dev_link(i->dev, j->dev); |
4686 | if (ret) | 4809 | if (ret) |
4687 | goto rollback_mesh; | 4810 | goto rollback_mesh; |
@@ -4689,14 +4812,18 @@ static int __netdev_upper_dev_link(struct net_device *dev, | |||
4689 | } | 4812 | } |
4690 | 4813 | ||
4691 | /* add dev to every upper_dev's upper device */ | 4814 | /* add dev to every upper_dev's upper device */ |
4692 | list_for_each_entry(i, &upper_dev->upper_dev_list, list) { | 4815 | list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) { |
4816 | pr_debug("linking %s's upper device %s with %s\n", | ||
4817 | upper_dev->name, i->dev->name, dev->name); | ||
4693 | ret = __netdev_adjacent_dev_link(dev, i->dev); | 4818 | ret = __netdev_adjacent_dev_link(dev, i->dev); |
4694 | if (ret) | 4819 | if (ret) |
4695 | goto rollback_upper_mesh; | 4820 | goto rollback_upper_mesh; |
4696 | } | 4821 | } |
4697 | 4822 | ||
4698 | /* add upper_dev to every dev's lower device */ | 4823 | /* add upper_dev to every dev's lower device */ |
4699 | list_for_each_entry(i, &dev->lower_dev_list, list) { | 4824 | list_for_each_entry(i, &dev->all_adj_list.lower, list) { |
4825 | pr_debug("linking %s's lower device %s with %s\n", dev->name, | ||
4826 | i->dev->name, upper_dev->name); | ||
4700 | ret = __netdev_adjacent_dev_link(i->dev, upper_dev); | 4827 | ret = __netdev_adjacent_dev_link(i->dev, upper_dev); |
4701 | if (ret) | 4828 | if (ret) |
4702 | goto rollback_lower_mesh; | 4829 | goto rollback_lower_mesh; |
@@ -4707,7 +4834,7 @@ static int __netdev_upper_dev_link(struct net_device *dev, | |||
4707 | 4834 | ||
4708 | rollback_lower_mesh: | 4835 | rollback_lower_mesh: |
4709 | to_i = i; | 4836 | to_i = i; |
4710 | list_for_each_entry(i, &dev->lower_dev_list, list) { | 4837 | list_for_each_entry(i, &dev->all_adj_list.lower, list) { |
4711 | if (i == to_i) | 4838 | if (i == to_i) |
4712 | break; | 4839 | break; |
4713 | __netdev_adjacent_dev_unlink(i->dev, upper_dev); | 4840 | __netdev_adjacent_dev_unlink(i->dev, upper_dev); |
@@ -4717,7 +4844,7 @@ rollback_lower_mesh: | |||
4717 | 4844 | ||
4718 | rollback_upper_mesh: | 4845 | rollback_upper_mesh: |
4719 | to_i = i; | 4846 | to_i = i; |
4720 | list_for_each_entry(i, &upper_dev->upper_dev_list, list) { | 4847 | list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) { |
4721 | if (i == to_i) | 4848 | if (i == to_i) |
4722 | break; | 4849 | break; |
4723 | __netdev_adjacent_dev_unlink(dev, i->dev); | 4850 | __netdev_adjacent_dev_unlink(dev, i->dev); |
@@ -4728,8 +4855,8 @@ rollback_upper_mesh: | |||
4728 | rollback_mesh: | 4855 | rollback_mesh: |
4729 | to_i = i; | 4856 | to_i = i; |
4730 | to_j = j; | 4857 | to_j = j; |
4731 | list_for_each_entry(i, &dev->lower_dev_list, list) { | 4858 | list_for_each_entry(i, &dev->all_adj_list.lower, list) { |
4732 | list_for_each_entry(j, &upper_dev->upper_dev_list, list) { | 4859 | list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) { |
4733 | if (i == to_i && j == to_j) | 4860 | if (i == to_i && j == to_j) |
4734 | break; | 4861 | break; |
4735 | __netdev_adjacent_dev_unlink(i->dev, j->dev); | 4862 | __netdev_adjacent_dev_unlink(i->dev, j->dev); |
@@ -4738,7 +4865,7 @@ rollback_mesh: | |||
4738 | break; | 4865 | break; |
4739 | } | 4866 | } |
4740 | 4867 | ||
4741 | __netdev_adjacent_dev_unlink(dev, upper_dev); | 4868 | __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev); |
4742 | 4869 | ||
4743 | return ret; | 4870 | return ret; |
4744 | } | 4871 | } |
@@ -4756,7 +4883,7 @@ rollback_mesh: | |||
4756 | int netdev_upper_dev_link(struct net_device *dev, | 4883 | int netdev_upper_dev_link(struct net_device *dev, |
4757 | struct net_device *upper_dev) | 4884 | struct net_device *upper_dev) |
4758 | { | 4885 | { |
4759 | return __netdev_upper_dev_link(dev, upper_dev, false); | 4886 | return __netdev_upper_dev_link(dev, upper_dev, false, NULL); |
4760 | } | 4887 | } |
4761 | EXPORT_SYMBOL(netdev_upper_dev_link); | 4888 | EXPORT_SYMBOL(netdev_upper_dev_link); |
4762 | 4889 | ||
@@ -4774,10 +4901,18 @@ EXPORT_SYMBOL(netdev_upper_dev_link); | |||
4774 | int netdev_master_upper_dev_link(struct net_device *dev, | 4901 | int netdev_master_upper_dev_link(struct net_device *dev, |
4775 | struct net_device *upper_dev) | 4902 | struct net_device *upper_dev) |
4776 | { | 4903 | { |
4777 | return __netdev_upper_dev_link(dev, upper_dev, true); | 4904 | return __netdev_upper_dev_link(dev, upper_dev, true, NULL); |
4778 | } | 4905 | } |
4779 | EXPORT_SYMBOL(netdev_master_upper_dev_link); | 4906 | EXPORT_SYMBOL(netdev_master_upper_dev_link); |
4780 | 4907 | ||
4908 | int netdev_master_upper_dev_link_private(struct net_device *dev, | ||
4909 | struct net_device *upper_dev, | ||
4910 | void *private) | ||
4911 | { | ||
4912 | return __netdev_upper_dev_link(dev, upper_dev, true, private); | ||
4913 | } | ||
4914 | EXPORT_SYMBOL(netdev_master_upper_dev_link_private); | ||
4915 | |||
4781 | /** | 4916 | /** |
4782 | * netdev_upper_dev_unlink - Removes a link to upper device | 4917 | * netdev_upper_dev_unlink - Removes a link to upper device |
4783 | * @dev: device | 4918 | * @dev: device |
@@ -4792,29 +4927,59 @@ void netdev_upper_dev_unlink(struct net_device *dev, | |||
4792 | struct netdev_adjacent *i, *j; | 4927 | struct netdev_adjacent *i, *j; |
4793 | ASSERT_RTNL(); | 4928 | ASSERT_RTNL(); |
4794 | 4929 | ||
4795 | __netdev_adjacent_dev_unlink(dev, upper_dev); | 4930 | __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev); |
4796 | 4931 | ||
4797 | /* Here is the tricky part. We must remove all dev's lower | 4932 | /* Here is the tricky part. We must remove all dev's lower |
4798 | * devices from all upper_dev's upper devices and vice | 4933 | * devices from all upper_dev's upper devices and vice |
4799 | * versa, to maintain the graph relationship. | 4934 | * versa, to maintain the graph relationship. |
4800 | */ | 4935 | */ |
4801 | list_for_each_entry(i, &dev->lower_dev_list, list) | 4936 | list_for_each_entry(i, &dev->all_adj_list.lower, list) |
4802 | list_for_each_entry(j, &upper_dev->upper_dev_list, list) | 4937 | list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) |
4803 | __netdev_adjacent_dev_unlink(i->dev, j->dev); | 4938 | __netdev_adjacent_dev_unlink(i->dev, j->dev); |
4804 | 4939 | ||
4805 | /* remove also the devices itself from lower/upper device | 4940 | /* remove also the devices itself from lower/upper device |
4806 | * list | 4941 | * list |
4807 | */ | 4942 | */ |
4808 | list_for_each_entry(i, &dev->lower_dev_list, list) | 4943 | list_for_each_entry(i, &dev->all_adj_list.lower, list) |
4809 | __netdev_adjacent_dev_unlink(i->dev, upper_dev); | 4944 | __netdev_adjacent_dev_unlink(i->dev, upper_dev); |
4810 | 4945 | ||
4811 | list_for_each_entry(i, &upper_dev->upper_dev_list, list) | 4946 | list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) |
4812 | __netdev_adjacent_dev_unlink(dev, i->dev); | 4947 | __netdev_adjacent_dev_unlink(dev, i->dev); |
4813 | 4948 | ||
4814 | call_netdevice_notifiers(NETDEV_CHANGEUPPER, dev); | 4949 | call_netdevice_notifiers(NETDEV_CHANGEUPPER, dev); |
4815 | } | 4950 | } |
4816 | EXPORT_SYMBOL(netdev_upper_dev_unlink); | 4951 | EXPORT_SYMBOL(netdev_upper_dev_unlink); |
4817 | 4952 | ||
4953 | void *netdev_lower_dev_get_private_rcu(struct net_device *dev, | ||
4954 | struct net_device *lower_dev) | ||
4955 | { | ||
4956 | struct netdev_adjacent *lower; | ||
4957 | |||
4958 | if (!lower_dev) | ||
4959 | return NULL; | ||
4960 | lower = __netdev_find_adj_rcu(dev, lower_dev, &dev->adj_list.lower); | ||
4961 | if (!lower) | ||
4962 | return NULL; | ||
4963 | |||
4964 | return lower->private; | ||
4965 | } | ||
4966 | EXPORT_SYMBOL(netdev_lower_dev_get_private_rcu); | ||
4967 | |||
4968 | void *netdev_lower_dev_get_private(struct net_device *dev, | ||
4969 | struct net_device *lower_dev) | ||
4970 | { | ||
4971 | struct netdev_adjacent *lower; | ||
4972 | |||
4973 | if (!lower_dev) | ||
4974 | return NULL; | ||
4975 | lower = __netdev_find_adj(dev, lower_dev, &dev->adj_list.lower); | ||
4976 | if (!lower) | ||
4977 | return NULL; | ||
4978 | |||
4979 | return lower->private; | ||
4980 | } | ||
4981 | EXPORT_SYMBOL(netdev_lower_dev_get_private); | ||
4982 | |||
4818 | static void dev_change_rx_flags(struct net_device *dev, int flags) | 4983 | static void dev_change_rx_flags(struct net_device *dev, int flags) |
4819 | { | 4984 | { |
4820 | const struct net_device_ops *ops = dev->netdev_ops; | 4985 | const struct net_device_ops *ops = dev->netdev_ops; |
@@ -4823,7 +4988,7 @@ static void dev_change_rx_flags(struct net_device *dev, int flags) | |||
4823 | ops->ndo_change_rx_flags(dev, flags); | 4988 | ops->ndo_change_rx_flags(dev, flags); |
4824 | } | 4989 | } |
4825 | 4990 | ||
4826 | static int __dev_set_promiscuity(struct net_device *dev, int inc) | 4991 | static int __dev_set_promiscuity(struct net_device *dev, int inc, bool notify) |
4827 | { | 4992 | { |
4828 | unsigned int old_flags = dev->flags; | 4993 | unsigned int old_flags = dev->flags; |
4829 | kuid_t uid; | 4994 | kuid_t uid; |
@@ -4866,6 +5031,8 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc) | |||
4866 | 5031 | ||
4867 | dev_change_rx_flags(dev, IFF_PROMISC); | 5032 | dev_change_rx_flags(dev, IFF_PROMISC); |
4868 | } | 5033 | } |
5034 | if (notify) | ||
5035 | __dev_notify_flags(dev, old_flags, IFF_PROMISC); | ||
4869 | return 0; | 5036 | return 0; |
4870 | } | 5037 | } |
4871 | 5038 | ||
@@ -4885,7 +5052,7 @@ int dev_set_promiscuity(struct net_device *dev, int inc) | |||
4885 | unsigned int old_flags = dev->flags; | 5052 | unsigned int old_flags = dev->flags; |
4886 | int err; | 5053 | int err; |
4887 | 5054 | ||
4888 | err = __dev_set_promiscuity(dev, inc); | 5055 | err = __dev_set_promiscuity(dev, inc, true); |
4889 | if (err < 0) | 5056 | if (err < 0) |
4890 | return err; | 5057 | return err; |
4891 | if (dev->flags != old_flags) | 5058 | if (dev->flags != old_flags) |
@@ -4894,22 +5061,9 @@ int dev_set_promiscuity(struct net_device *dev, int inc) | |||
4894 | } | 5061 | } |
4895 | EXPORT_SYMBOL(dev_set_promiscuity); | 5062 | EXPORT_SYMBOL(dev_set_promiscuity); |
4896 | 5063 | ||
4897 | /** | 5064 | static int __dev_set_allmulti(struct net_device *dev, int inc, bool notify) |
4898 | * dev_set_allmulti - update allmulti count on a device | ||
4899 | * @dev: device | ||
4900 | * @inc: modifier | ||
4901 | * | ||
4902 | * Add or remove reception of all multicast frames to a device. While the | ||
4903 | * count in the device remains above zero the interface remains listening | ||
4904 | * to all interfaces. Once it hits zero the device reverts back to normal | ||
4905 | * filtering operation. A negative @inc value is used to drop the counter | ||
4906 | * when releasing a resource needing all multicasts. | ||
4907 | * Return 0 if successful or a negative errno code on error. | ||
4908 | */ | ||
4909 | |||
4910 | int dev_set_allmulti(struct net_device *dev, int inc) | ||
4911 | { | 5065 | { |
4912 | unsigned int old_flags = dev->flags; | 5066 | unsigned int old_flags = dev->flags, old_gflags = dev->gflags; |
4913 | 5067 | ||
4914 | ASSERT_RTNL(); | 5068 | ASSERT_RTNL(); |
4915 | 5069 | ||
@@ -4932,9 +5086,30 @@ int dev_set_allmulti(struct net_device *dev, int inc) | |||
4932 | if (dev->flags ^ old_flags) { | 5086 | if (dev->flags ^ old_flags) { |
4933 | dev_change_rx_flags(dev, IFF_ALLMULTI); | 5087 | dev_change_rx_flags(dev, IFF_ALLMULTI); |
4934 | dev_set_rx_mode(dev); | 5088 | dev_set_rx_mode(dev); |
5089 | if (notify) | ||
5090 | __dev_notify_flags(dev, old_flags, | ||
5091 | dev->gflags ^ old_gflags); | ||
4935 | } | 5092 | } |
4936 | return 0; | 5093 | return 0; |
4937 | } | 5094 | } |
5095 | |||
5096 | /** | ||
5097 | * dev_set_allmulti - update allmulti count on a device | ||
5098 | * @dev: device | ||
5099 | * @inc: modifier | ||
5100 | * | ||
5101 | * Add or remove reception of all multicast frames to a device. While the | ||
5102 | * count in the device remains above zero the interface remains listening | ||
5103 | * to all interfaces. Once it hits zero the device reverts back to normal | ||
5104 | * filtering operation. A negative @inc value is used to drop the counter | ||
5105 | * when releasing a resource needing all multicasts. | ||
5106 | * Return 0 if successful or a negative errno code on error. | ||
5107 | */ | ||
5108 | |||
5109 | int dev_set_allmulti(struct net_device *dev, int inc) | ||
5110 | { | ||
5111 | return __dev_set_allmulti(dev, inc, true); | ||
5112 | } | ||
4938 | EXPORT_SYMBOL(dev_set_allmulti); | 5113 | EXPORT_SYMBOL(dev_set_allmulti); |
4939 | 5114 | ||
4940 | /* | 5115 | /* |
@@ -4959,10 +5134,10 @@ void __dev_set_rx_mode(struct net_device *dev) | |||
4959 | * therefore calling __dev_set_promiscuity here is safe. | 5134 | * therefore calling __dev_set_promiscuity here is safe. |
4960 | */ | 5135 | */ |
4961 | if (!netdev_uc_empty(dev) && !dev->uc_promisc) { | 5136 | if (!netdev_uc_empty(dev) && !dev->uc_promisc) { |
4962 | __dev_set_promiscuity(dev, 1); | 5137 | __dev_set_promiscuity(dev, 1, false); |
4963 | dev->uc_promisc = true; | 5138 | dev->uc_promisc = true; |
4964 | } else if (netdev_uc_empty(dev) && dev->uc_promisc) { | 5139 | } else if (netdev_uc_empty(dev) && dev->uc_promisc) { |
4965 | __dev_set_promiscuity(dev, -1); | 5140 | __dev_set_promiscuity(dev, -1, false); |
4966 | dev->uc_promisc = false; | 5141 | dev->uc_promisc = false; |
4967 | } | 5142 | } |
4968 | } | 5143 | } |
@@ -5051,9 +5226,13 @@ int __dev_change_flags(struct net_device *dev, unsigned int flags) | |||
5051 | 5226 | ||
5052 | if ((flags ^ dev->gflags) & IFF_PROMISC) { | 5227 | if ((flags ^ dev->gflags) & IFF_PROMISC) { |
5053 | int inc = (flags & IFF_PROMISC) ? 1 : -1; | 5228 | int inc = (flags & IFF_PROMISC) ? 1 : -1; |
5229 | unsigned int old_flags = dev->flags; | ||
5054 | 5230 | ||
5055 | dev->gflags ^= IFF_PROMISC; | 5231 | dev->gflags ^= IFF_PROMISC; |
5056 | dev_set_promiscuity(dev, inc); | 5232 | |
5233 | if (__dev_set_promiscuity(dev, inc, false) >= 0) | ||
5234 | if (dev->flags != old_flags) | ||
5235 | dev_set_rx_mode(dev); | ||
5057 | } | 5236 | } |
5058 | 5237 | ||
5059 | /* NOTE: order of synchronization of IFF_PROMISC and IFF_ALLMULTI | 5238 | /* NOTE: order of synchronization of IFF_PROMISC and IFF_ALLMULTI |
@@ -5064,16 +5243,20 @@ int __dev_change_flags(struct net_device *dev, unsigned int flags) | |||
5064 | int inc = (flags & IFF_ALLMULTI) ? 1 : -1; | 5243 | int inc = (flags & IFF_ALLMULTI) ? 1 : -1; |
5065 | 5244 | ||
5066 | dev->gflags ^= IFF_ALLMULTI; | 5245 | dev->gflags ^= IFF_ALLMULTI; |
5067 | dev_set_allmulti(dev, inc); | 5246 | __dev_set_allmulti(dev, inc, false); |
5068 | } | 5247 | } |
5069 | 5248 | ||
5070 | return ret; | 5249 | return ret; |
5071 | } | 5250 | } |
5072 | 5251 | ||
5073 | void __dev_notify_flags(struct net_device *dev, unsigned int old_flags) | 5252 | void __dev_notify_flags(struct net_device *dev, unsigned int old_flags, |
5253 | unsigned int gchanges) | ||
5074 | { | 5254 | { |
5075 | unsigned int changes = dev->flags ^ old_flags; | 5255 | unsigned int changes = dev->flags ^ old_flags; |
5076 | 5256 | ||
5257 | if (gchanges) | ||
5258 | rtmsg_ifinfo(RTM_NEWLINK, dev, gchanges); | ||
5259 | |||
5077 | if (changes & IFF_UP) { | 5260 | if (changes & IFF_UP) { |
5078 | if (dev->flags & IFF_UP) | 5261 | if (dev->flags & IFF_UP) |
5079 | call_netdevice_notifiers(NETDEV_UP, dev); | 5262 | call_netdevice_notifiers(NETDEV_UP, dev); |
@@ -5102,17 +5285,14 @@ void __dev_notify_flags(struct net_device *dev, unsigned int old_flags) | |||
5102 | int dev_change_flags(struct net_device *dev, unsigned int flags) | 5285 | int dev_change_flags(struct net_device *dev, unsigned int flags) |
5103 | { | 5286 | { |
5104 | int ret; | 5287 | int ret; |
5105 | unsigned int changes, old_flags = dev->flags; | 5288 | unsigned int changes, old_flags = dev->flags, old_gflags = dev->gflags; |
5106 | 5289 | ||
5107 | ret = __dev_change_flags(dev, flags); | 5290 | ret = __dev_change_flags(dev, flags); |
5108 | if (ret < 0) | 5291 | if (ret < 0) |
5109 | return ret; | 5292 | return ret; |
5110 | 5293 | ||
5111 | changes = old_flags ^ dev->flags; | 5294 | changes = (old_flags ^ dev->flags) | (old_gflags ^ dev->gflags); |
5112 | if (changes) | 5295 | __dev_notify_flags(dev, old_flags, changes); |
5113 | rtmsg_ifinfo(RTM_NEWLINK, dev, changes); | ||
5114 | |||
5115 | __dev_notify_flags(dev, old_flags); | ||
5116 | return ret; | 5296 | return ret; |
5117 | } | 5297 | } |
5118 | EXPORT_SYMBOL(dev_change_flags); | 5298 | EXPORT_SYMBOL(dev_change_flags); |
@@ -5259,6 +5439,7 @@ static void net_set_todo(struct net_device *dev) | |||
5259 | static void rollback_registered_many(struct list_head *head) | 5439 | static void rollback_registered_many(struct list_head *head) |
5260 | { | 5440 | { |
5261 | struct net_device *dev, *tmp; | 5441 | struct net_device *dev, *tmp; |
5442 | LIST_HEAD(close_head); | ||
5262 | 5443 | ||
5263 | BUG_ON(dev_boot_phase); | 5444 | BUG_ON(dev_boot_phase); |
5264 | ASSERT_RTNL(); | 5445 | ASSERT_RTNL(); |
@@ -5281,7 +5462,9 @@ static void rollback_registered_many(struct list_head *head) | |||
5281 | } | 5462 | } |
5282 | 5463 | ||
5283 | /* If device is running, close it first. */ | 5464 | /* If device is running, close it first. */ |
5284 | dev_close_many(head); | 5465 | list_for_each_entry(dev, head, unreg_list) |
5466 | list_add_tail(&dev->close_list, &close_head); | ||
5467 | dev_close_many(&close_head); | ||
5285 | 5468 | ||
5286 | list_for_each_entry(dev, head, unreg_list) { | 5469 | list_for_each_entry(dev, head, unreg_list) { |
5287 | /* And unlink it from device chain. */ | 5470 | /* And unlink it from device chain. */ |
@@ -6077,9 +6260,12 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, | |||
6077 | 6260 | ||
6078 | INIT_LIST_HEAD(&dev->napi_list); | 6261 | INIT_LIST_HEAD(&dev->napi_list); |
6079 | INIT_LIST_HEAD(&dev->unreg_list); | 6262 | INIT_LIST_HEAD(&dev->unreg_list); |
6263 | INIT_LIST_HEAD(&dev->close_list); | ||
6080 | INIT_LIST_HEAD(&dev->link_watch_list); | 6264 | INIT_LIST_HEAD(&dev->link_watch_list); |
6081 | INIT_LIST_HEAD(&dev->upper_dev_list); | 6265 | INIT_LIST_HEAD(&dev->adj_list.upper); |
6082 | INIT_LIST_HEAD(&dev->lower_dev_list); | 6266 | INIT_LIST_HEAD(&dev->adj_list.lower); |
6267 | INIT_LIST_HEAD(&dev->all_adj_list.upper); | ||
6268 | INIT_LIST_HEAD(&dev->all_adj_list.lower); | ||
6083 | dev->priv_flags = IFF_XMIT_DST_RELEASE; | 6269 | dev->priv_flags = IFF_XMIT_DST_RELEASE; |
6084 | setup(dev); | 6270 | setup(dev); |
6085 | 6271 | ||
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 8d7d0dd72db2..f8e25ac41c6c 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c | |||
@@ -25,9 +25,35 @@ static void iph_to_flow_copy_addrs(struct flow_keys *flow, const struct iphdr *i | |||
25 | memcpy(&flow->src, &iph->saddr, sizeof(flow->src) + sizeof(flow->dst)); | 25 | memcpy(&flow->src, &iph->saddr, sizeof(flow->src) + sizeof(flow->dst)); |
26 | } | 26 | } |
27 | 27 | ||
28 | /** | ||
29 | * skb_flow_get_ports - extract the upper layer ports and return them | ||
30 | * @skb: buffer to extract the ports from | ||
31 | * @thoff: transport header offset | ||
32 | * @ip_proto: protocol for which to get port offset | ||
33 | * | ||
34 | * The function will try to retrieve the ports at offset thoff + poff where poff | ||
35 | * is the protocol port offset returned from proto_ports_offset | ||
36 | */ | ||
37 | __be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto) | ||
38 | { | ||
39 | int poff = proto_ports_offset(ip_proto); | ||
40 | |||
41 | if (poff >= 0) { | ||
42 | __be32 *ports, _ports; | ||
43 | |||
44 | ports = skb_header_pointer(skb, thoff + poff, | ||
45 | sizeof(_ports), &_ports); | ||
46 | if (ports) | ||
47 | return *ports; | ||
48 | } | ||
49 | |||
50 | return 0; | ||
51 | } | ||
52 | EXPORT_SYMBOL(skb_flow_get_ports); | ||
53 | |||
28 | bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow) | 54 | bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow) |
29 | { | 55 | { |
30 | int poff, nhoff = skb_network_offset(skb); | 56 | int nhoff = skb_network_offset(skb); |
31 | u8 ip_proto; | 57 | u8 ip_proto; |
32 | __be16 proto = skb->protocol; | 58 | __be16 proto = skb->protocol; |
33 | 59 | ||
@@ -150,16 +176,7 @@ ipv6: | |||
150 | } | 176 | } |
151 | 177 | ||
152 | flow->ip_proto = ip_proto; | 178 | flow->ip_proto = ip_proto; |
153 | poff = proto_ports_offset(ip_proto); | 179 | flow->ports = skb_flow_get_ports(skb, nhoff, ip_proto); |
154 | if (poff >= 0) { | ||
155 | __be32 *ports, _ports; | ||
156 | |||
157 | ports = skb_header_pointer(skb, nhoff + poff, | ||
158 | sizeof(_ports), &_ports); | ||
159 | if (ports) | ||
160 | flow->ports = *ports; | ||
161 | } | ||
162 | |||
163 | flow->thoff = (u16) nhoff; | 180 | flow->thoff = (u16) nhoff; |
164 | 181 | ||
165 | return true; | 182 | return true; |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 6072610a8672..ca15f32821fb 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -867,7 +867,7 @@ static void neigh_invalidate(struct neighbour *neigh) | |||
867 | static void neigh_probe(struct neighbour *neigh) | 867 | static void neigh_probe(struct neighbour *neigh) |
868 | __releases(neigh->lock) | 868 | __releases(neigh->lock) |
869 | { | 869 | { |
870 | struct sk_buff *skb = skb_peek(&neigh->arp_queue); | 870 | struct sk_buff *skb = skb_peek_tail(&neigh->arp_queue); |
871 | /* keep skb alive even if arp_queue overflows */ | 871 | /* keep skb alive even if arp_queue overflows */ |
872 | if (skb) | 872 | if (skb) |
873 | skb = skb_copy(skb, GFP_ATOMIC); | 873 | skb = skb_copy(skb, GFP_ATOMIC); |
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index d9cd627e6a16..9b7cf6c85f82 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c | |||
@@ -222,11 +222,10 @@ static void net_prio_attach(struct cgroup_subsys_state *css, | |||
222 | struct cgroup_taskset *tset) | 222 | struct cgroup_taskset *tset) |
223 | { | 223 | { |
224 | struct task_struct *p; | 224 | struct task_struct *p; |
225 | void *v; | 225 | void *v = (void *)(unsigned long)css->cgroup->id; |
226 | 226 | ||
227 | cgroup_taskset_for_each(p, css, tset) { | 227 | cgroup_taskset_for_each(p, css, tset) { |
228 | task_lock(p); | 228 | task_lock(p); |
229 | v = (void *)(unsigned long)task_netprioidx(p); | ||
230 | iterate_fd(p->files, 0, update_netprio, v); | 229 | iterate_fd(p->files, 0, update_netprio, v); |
231 | task_unlock(p); | 230 | task_unlock(p); |
232 | } | 231 | } |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 2a0e21de3060..4aedf03da052 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1647,9 +1647,8 @@ int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm) | |||
1647 | } | 1647 | } |
1648 | 1648 | ||
1649 | dev->rtnl_link_state = RTNL_LINK_INITIALIZED; | 1649 | dev->rtnl_link_state = RTNL_LINK_INITIALIZED; |
1650 | rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); | ||
1651 | 1650 | ||
1652 | __dev_notify_flags(dev, old_flags); | 1651 | __dev_notify_flags(dev, old_flags, ~0U); |
1653 | return 0; | 1652 | return 0; |
1654 | } | 1653 | } |
1655 | EXPORT_SYMBOL(rtnl_configure_link); | 1654 | EXPORT_SYMBOL(rtnl_configure_link); |
diff --git a/net/core/sock.c b/net/core/sock.c index 0b39e7ae4383..fd6afa267475 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -914,6 +914,13 @@ set_rcvbuf: | |||
914 | } | 914 | } |
915 | break; | 915 | break; |
916 | #endif | 916 | #endif |
917 | |||
918 | case SO_MAX_PACING_RATE: | ||
919 | sk->sk_max_pacing_rate = val; | ||
920 | sk->sk_pacing_rate = min(sk->sk_pacing_rate, | ||
921 | sk->sk_max_pacing_rate); | ||
922 | break; | ||
923 | |||
917 | default: | 924 | default: |
918 | ret = -ENOPROTOOPT; | 925 | ret = -ENOPROTOOPT; |
919 | break; | 926 | break; |
@@ -1177,6 +1184,10 @@ int sock_getsockopt(struct socket *sock, int level, int optname, | |||
1177 | break; | 1184 | break; |
1178 | #endif | 1185 | #endif |
1179 | 1186 | ||
1187 | case SO_MAX_PACING_RATE: | ||
1188 | v.val = sk->sk_max_pacing_rate; | ||
1189 | break; | ||
1190 | |||
1180 | default: | 1191 | default: |
1181 | return -ENOPROTOOPT; | 1192 | return -ENOPROTOOPT; |
1182 | } | 1193 | } |
@@ -2319,6 +2330,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) | |||
2319 | sk->sk_ll_usec = sysctl_net_busy_read; | 2330 | sk->sk_ll_usec = sysctl_net_busy_read; |
2320 | #endif | 2331 | #endif |
2321 | 2332 | ||
2333 | sk->sk_max_pacing_rate = ~0U; | ||
2322 | sk->sk_pacing_rate = ~0U; | 2334 | sk->sk_pacing_rate = ~0U; |
2323 | /* | 2335 | /* |
2324 | * Before updating sk_refcnt, we must commit prior changes to memory | 2336 | * Before updating sk_refcnt, we must commit prior changes to memory |