aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/dev.c')
-rw-r--r--net/core/dev.c404
1 files changed, 286 insertions, 118 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 5c713f2239cc..25ab6fe80da2 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4373,42 +4373,40 @@ struct netdev_adjacent {
4373 /* 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 */
4374 bool master; 4374 bool master;
4375 4375
4376 /* indicates that this dev is our first-level lower/upper device */
4377 bool neighbour;
4378
4379 /* 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 */
4380 u16 ref_nr; 4377 u16 ref_nr;
4381 4378
4379 /* private field for the users */
4380 void *private;
4381
4382 struct list_head list; 4382 struct list_head list;
4383 struct rcu_head rcu; 4383 struct rcu_head rcu;
4384}; 4384};
4385 4385
4386static struct netdev_adjacent *__netdev_find_adj(struct net_device *dev, 4386static struct netdev_adjacent *__netdev_find_adj_rcu(struct net_device *dev,
4387 struct net_device *adj_dev, 4387 struct net_device *adj_dev,
4388 bool upper) 4388 struct list_head *adj_list)
4389{ 4389{
4390 struct netdev_adjacent *adj; 4390 struct netdev_adjacent *adj;
4391 struct list_head *dev_list;
4392 4391
4393 dev_list = upper ? &dev->upper_dev_list : &dev->lower_dev_list; 4392 list_for_each_entry_rcu(adj, adj_list, list) {
4394
4395 list_for_each_entry(adj, dev_list, list) {
4396 if (adj->dev == adj_dev) 4393 if (adj->dev == adj_dev)
4397 return adj; 4394 return adj;
4398 } 4395 }
4399 return NULL; 4396 return NULL;
4400} 4397}
4401 4398
4402static inline struct netdev_adjacent *__netdev_find_upper(struct net_device *dev, 4399static struct netdev_adjacent *__netdev_find_adj(struct net_device *dev,
4403 struct net_device *udev) 4400 struct net_device *adj_dev,
4401 struct list_head *adj_list)
4404{ 4402{
4405 return __netdev_find_adj(dev, udev, true); 4403 struct netdev_adjacent *adj;
4406}
4407 4404
4408static inline struct netdev_adjacent *__netdev_find_lower(struct net_device *dev, 4405 list_for_each_entry(adj, adj_list, list) {
4409 struct net_device *ldev) 4406 if (adj->dev == adj_dev)
4410{ 4407 return adj;
4411 return __netdev_find_adj(dev, ldev, false); 4408 }
4409 return NULL;
4412} 4410}
4413 4411
4414/** 4412/**
@@ -4425,7 +4423,7 @@ bool netdev_has_upper_dev(struct net_device *dev,
4425{ 4423{
4426 ASSERT_RTNL(); 4424 ASSERT_RTNL();
4427 4425
4428 return __netdev_find_upper(dev, upper_dev); 4426 return __netdev_find_adj(dev, upper_dev, &dev->all_adj_list.upper);
4429} 4427}
4430EXPORT_SYMBOL(netdev_has_upper_dev); 4428EXPORT_SYMBOL(netdev_has_upper_dev);
4431 4429
@@ -4440,7 +4438,7 @@ bool netdev_has_any_upper_dev(struct net_device *dev)
4440{ 4438{
4441 ASSERT_RTNL(); 4439 ASSERT_RTNL();
4442 4440
4443 return !list_empty(&dev->upper_dev_list); 4441 return !list_empty(&dev->all_adj_list.upper);
4444} 4442}
4445EXPORT_SYMBOL(netdev_has_any_upper_dev); 4443EXPORT_SYMBOL(netdev_has_any_upper_dev);
4446 4444
@@ -4457,10 +4455,10 @@ struct net_device *netdev_master_upper_dev_get(struct net_device *dev)
4457 4455
4458 ASSERT_RTNL(); 4456 ASSERT_RTNL();
4459 4457
4460 if (list_empty(&dev->upper_dev_list)) 4458 if (list_empty(&dev->adj_list.upper))
4461 return NULL; 4459 return NULL;
4462 4460
4463 upper = list_first_entry(&dev->upper_dev_list, 4461 upper = list_first_entry(&dev->adj_list.upper,
4464 struct netdev_adjacent, list); 4462 struct netdev_adjacent, list);
4465 if (likely(upper->master)) 4463 if (likely(upper->master))
4466 return upper->dev; 4464 return upper->dev;
@@ -4468,15 +4466,26 @@ struct net_device *netdev_master_upper_dev_get(struct net_device *dev)
4468} 4466}
4469EXPORT_SYMBOL(netdev_master_upper_dev_get); 4467EXPORT_SYMBOL(netdev_master_upper_dev_get);
4470 4468
4471/* netdev_upper_get_next_dev_rcu - Get the next dev from upper list 4469void *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}
4477EXPORT_SYMBOL(netdev_adjacent_get_private);
4478
4479/**
4480 * netdev_all_upper_get_next_dev_rcu - Get the next dev from upper list
4472 * @dev: device 4481 * @dev: device
4473 * @iter: list_head ** of the current position 4482 * @iter: list_head ** of the current position
4474 * 4483 *
4475 * 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
4476 * position. The caller must hold RCU read lock. 4485 * position. The caller must hold RCU read lock.
4477 */ 4486 */
4478struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev, 4487struct net_device *netdev_all_upper_get_next_dev_rcu(struct net_device *dev,
4479 struct list_head **iter) 4488 struct list_head **iter)
4480{ 4489{
4481 struct netdev_adjacent *upper; 4490 struct netdev_adjacent *upper;
4482 4491
@@ -4484,14 +4493,71 @@ struct net_device *netdev_upper_get_next_dev_rcu(struct net_device *dev,
4484 4493
4485 upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list); 4494 upper = list_entry_rcu((*iter)->next, struct netdev_adjacent, list);
4486 4495
4487 if (&upper->list == &dev->upper_dev_list) 4496 if (&upper->list == &dev->all_adj_list.upper)
4488 return NULL; 4497 return NULL;
4489 4498
4490 *iter = &upper->list; 4499 *iter = &upper->list;
4491 4500
4492 return upper->dev; 4501 return upper->dev;
4493} 4502}
4494EXPORT_SYMBOL(netdev_upper_get_next_dev_rcu); 4503EXPORT_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 */
4516void *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}
4531EXPORT_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 */
4543void *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}
4560EXPORT_SYMBOL(netdev_lower_get_next_private_rcu);
4495 4561
4496/** 4562/**
4497 * netdev_master_upper_dev_get_rcu - Get master upper device 4563 * netdev_master_upper_dev_get_rcu - Get master upper device
@@ -4504,7 +4570,7 @@ struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev)
4504{ 4570{
4505 struct netdev_adjacent *upper; 4571 struct netdev_adjacent *upper;
4506 4572
4507 upper = list_first_or_null_rcu(&dev->upper_dev_list, 4573 upper = list_first_or_null_rcu(&dev->adj_list.upper,
4508 struct netdev_adjacent, list); 4574 struct netdev_adjacent, list);
4509 if (upper && likely(upper->master)) 4575 if (upper && likely(upper->master))
4510 return upper->dev; 4576 return upper->dev;
@@ -4514,15 +4580,16 @@ EXPORT_SYMBOL(netdev_master_upper_dev_get_rcu);
4514 4580
4515static int __netdev_adjacent_dev_insert(struct net_device *dev, 4581static int __netdev_adjacent_dev_insert(struct net_device *dev,
4516 struct net_device *adj_dev, 4582 struct net_device *adj_dev,
4517 bool neighbour, bool master, 4583 struct list_head *dev_list,
4518 bool upper) 4584 void *private, bool master)
4519{ 4585{
4520 struct netdev_adjacent *adj; 4586 struct netdev_adjacent *adj;
4587 char linkname[IFNAMSIZ+7];
4588 int ret;
4521 4589
4522 adj = __netdev_find_adj(dev, adj_dev, upper); 4590 adj = __netdev_find_adj(dev, adj_dev, dev_list);
4523 4591
4524 if (adj) { 4592 if (adj) {
4525 BUG_ON(neighbour);
4526 adj->ref_nr++; 4593 adj->ref_nr++;
4527 return 0; 4594 return 0;
4528 } 4595 }
@@ -4533,124 +4600,178 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
4533 4600
4534 adj->dev = adj_dev; 4601 adj->dev = adj_dev;
4535 adj->master = master; 4602 adj->master = master;
4536 adj->neighbour = neighbour;
4537 adj->ref_nr = 1; 4603 adj->ref_nr = 1;
4538 4604 adj->private = private;
4539 dev_hold(adj_dev); 4605 dev_hold(adj_dev);
4540 pr_debug("dev_hold for %s, because of %s link added from %s to %s\n",
4541 adj_dev->name, upper ? "upper" : "lower", dev->name,
4542 adj_dev->name);
4543 4606
4544 if (!upper) { 4607 pr_debug("dev_hold for %s, because of link added from %s to %s\n",
4545 list_add_tail_rcu(&adj->list, &dev->lower_dev_list); 4608 adj_dev->name, dev->name, adj_dev->name);
4546 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;
4547 } 4622 }
4548 4623
4549 /* Ensure that master upper link is always the first item in list. */ 4624 /* Ensure that master link is always the first item in list. */
4550 if (master) 4625 if (master) {
4551 list_add_rcu(&adj->list, &dev->upper_dev_list); 4626 ret = sysfs_create_link(&(dev->dev.kobj),
4552 else 4627 &(adj_dev->dev.kobj), "master");
4553 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 }
4554 4635
4555 return 0; 4636 return 0;
4556}
4557 4637
4558static inline int __netdev_upper_dev_insert(struct net_device *dev, 4638remove_symlinks:
4559 struct net_device *udev, 4639 if (dev_list == &dev->adj_list.lower) {
4560 bool master, bool neighbour) 4640 sprintf(linkname, "lower_%s", adj_dev->name);
4561{ 4641 sysfs_remove_link(&(dev->dev.kobj), linkname);
4562 return __netdev_adjacent_dev_insert(dev, udev, neighbour, master, 4642 } else if (dev_list == &dev->adj_list.upper) {
4563 true); 4643 sprintf(linkname, "upper_%s", adj_dev->name);
4564} 4644 sysfs_remove_link(&(dev->dev.kobj), linkname);
4645 }
4565 4646
4566static inline int __netdev_lower_dev_insert(struct net_device *dev, 4647free_adj:
4567 struct net_device *ldev, 4648 kfree(adj);
4568 bool neighbour) 4649
4569{ 4650 return ret;
4570 return __netdev_adjacent_dev_insert(dev, ldev, neighbour, false,
4571 false);
4572} 4651}
4573 4652
4574void __netdev_adjacent_dev_remove(struct net_device *dev, 4653void __netdev_adjacent_dev_remove(struct net_device *dev,
4575 struct net_device *adj_dev, bool upper) 4654 struct net_device *adj_dev,
4655 struct list_head *dev_list)
4576{ 4656{
4577 struct netdev_adjacent *adj; 4657 struct netdev_adjacent *adj;
4658 char linkname[IFNAMSIZ+7];
4578 4659
4579 if (upper) 4660 adj = __netdev_find_adj(dev, adj_dev, dev_list);
4580 adj = __netdev_find_upper(dev, adj_dev);
4581 else
4582 adj = __netdev_find_lower(dev, adj_dev);
4583 4661
4584 if (!adj) 4662 if (!adj) {
4663 pr_err("tried to remove device %s from %s\n",
4664 dev->name, adj_dev->name);
4585 BUG(); 4665 BUG();
4666 }
4586 4667
4587 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);
4588 adj->ref_nr--; 4671 adj->ref_nr--;
4589 return; 4672 return;
4590 } 4673 }
4591 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
4592 list_del_rcu(&adj->list); 4686 list_del_rcu(&adj->list);
4593 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",
4594 adj_dev->name, upper ? "upper" : "lower", dev->name, 4688 adj_dev->name, dev->name, adj_dev->name);
4595 adj_dev->name);
4596 dev_put(adj_dev); 4689 dev_put(adj_dev);
4597 kfree_rcu(adj, rcu); 4690 kfree_rcu(adj, rcu);
4598} 4691}
4599 4692
4600static inline void __netdev_upper_dev_remove(struct net_device *dev, 4693int __netdev_adjacent_dev_link_lists(struct net_device *dev,
4601 struct net_device *udev) 4694 struct net_device *upper_dev,
4602{ 4695 struct list_head *up_list,
4603 return __netdev_adjacent_dev_remove(dev, udev, true); 4696 struct list_head *down_list,
4604} 4697 void *private, bool master)
4605
4606static inline void __netdev_lower_dev_remove(struct net_device *dev,
4607 struct net_device *ldev)
4608{
4609 return __netdev_adjacent_dev_remove(dev, ldev, false);
4610}
4611
4612int __netdev_adjacent_dev_insert_link(struct net_device *dev,
4613 struct net_device *upper_dev,
4614 bool master, bool neighbour)
4615{ 4698{
4616 int ret; 4699 int ret;
4617 4700
4618 ret = __netdev_upper_dev_insert(dev, upper_dev, master, neighbour); 4701 ret = __netdev_adjacent_dev_insert(dev, upper_dev, up_list, private,
4702 master);
4619 if (ret) 4703 if (ret)
4620 return ret; 4704 return ret;
4621 4705
4622 ret = __netdev_lower_dev_insert(upper_dev, dev, neighbour); 4706 ret = __netdev_adjacent_dev_insert(upper_dev, dev, down_list, private,
4707 false);
4623 if (ret) { 4708 if (ret) {
4624 __netdev_upper_dev_remove(dev, upper_dev); 4709 __netdev_adjacent_dev_remove(dev, upper_dev, up_list);
4625 return ret; 4710 return ret;
4626 } 4711 }
4627 4712
4628 return 0; 4713 return 0;
4629} 4714}
4630 4715
4631static inline int __netdev_adjacent_dev_link(struct net_device *dev, 4716int __netdev_adjacent_dev_link(struct net_device *dev,
4632 struct net_device *udev) 4717 struct net_device *upper_dev)
4633{ 4718{
4634 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);
4635} 4723}
4636 4724
4637static inline int __netdev_adjacent_dev_link_neighbour(struct net_device *dev, 4725void __netdev_adjacent_dev_unlink_lists(struct net_device *dev,
4638 struct net_device *udev, 4726 struct net_device *upper_dev,
4639 bool master) 4727 struct list_head *up_list,
4728 struct list_head *down_list)
4640{ 4729{
4641 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);
4642} 4732}
4643 4733
4644void __netdev_adjacent_dev_unlink(struct net_device *dev, 4734void __netdev_adjacent_dev_unlink(struct net_device *dev,
4645 struct net_device *upper_dev) 4735 struct net_device *upper_dev)
4646{ 4736{
4647 __netdev_upper_dev_remove(dev, upper_dev); 4737 __netdev_adjacent_dev_unlink_lists(dev, upper_dev,
4648 __netdev_lower_dev_remove(upper_dev, dev); 4738 &dev->all_adj_list.upper,
4739 &upper_dev->all_adj_list.lower);
4740}
4741
4742int __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;
4649} 4761}
4650 4762
4763void __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}
4651 4771
4652static int __netdev_upper_dev_link(struct net_device *dev, 4772static int __netdev_upper_dev_link(struct net_device *dev,
4653 struct net_device *upper_dev, bool master) 4773 struct net_device *upper_dev, bool master,
4774 void *private)
4654{ 4775{
4655 struct netdev_adjacent *i, *j, *to_i, *to_j; 4776 struct netdev_adjacent *i, *j, *to_i, *to_j;
4656 int ret = 0; 4777 int ret = 0;
@@ -4661,26 +4782,29 @@ static int __netdev_upper_dev_link(struct net_device *dev,
4661 return -EBUSY; 4782 return -EBUSY;
4662 4783
4663 /* 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. */
4664 if (__netdev_find_upper(upper_dev, dev)) 4785 if (__netdev_find_adj(upper_dev, dev, &upper_dev->all_adj_list.upper))
4665 return -EBUSY; 4786 return -EBUSY;
4666 4787
4667 if (__netdev_find_upper(dev, upper_dev)) 4788 if (__netdev_find_adj(dev, upper_dev, &dev->all_adj_list.upper))
4668 return -EEXIST; 4789 return -EEXIST;
4669 4790
4670 if (master && netdev_master_upper_dev_get(dev)) 4791 if (master && netdev_master_upper_dev_get(dev))
4671 return -EBUSY; 4792 return -EBUSY;
4672 4793
4673 ret = __netdev_adjacent_dev_link_neighbour(dev, upper_dev, master); 4794 ret = __netdev_adjacent_dev_link_neighbour(dev, upper_dev, private,
4795 master);
4674 if (ret) 4796 if (ret)
4675 return ret; 4797 return ret;
4676 4798
4677 /* 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
4678 * 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
4679 * versa, and don't forget the devices itself. All of these 4801 * versa, and don't forget the devices itself. All of these
4680 * links are non-neighbours. 4802 * links are non-neighbours.
4681 */ 4803 */
4682 list_for_each_entry(i, &dev->lower_dev_list, list) { 4804 list_for_each_entry(i, &dev->all_adj_list.lower, list) {
4683 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);
4684 ret = __netdev_adjacent_dev_link(i->dev, j->dev); 4808 ret = __netdev_adjacent_dev_link(i->dev, j->dev);
4685 if (ret) 4809 if (ret)
4686 goto rollback_mesh; 4810 goto rollback_mesh;
@@ -4688,14 +4812,18 @@ static int __netdev_upper_dev_link(struct net_device *dev,
4688 } 4812 }
4689 4813
4690 /* add dev to every upper_dev's upper device */ 4814 /* add dev to every upper_dev's upper device */
4691 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);
4692 ret = __netdev_adjacent_dev_link(dev, i->dev); 4818 ret = __netdev_adjacent_dev_link(dev, i->dev);
4693 if (ret) 4819 if (ret)
4694 goto rollback_upper_mesh; 4820 goto rollback_upper_mesh;
4695 } 4821 }
4696 4822
4697 /* add upper_dev to every dev's lower device */ 4823 /* add upper_dev to every dev's lower device */
4698 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);
4699 ret = __netdev_adjacent_dev_link(i->dev, upper_dev); 4827 ret = __netdev_adjacent_dev_link(i->dev, upper_dev);
4700 if (ret) 4828 if (ret)
4701 goto rollback_lower_mesh; 4829 goto rollback_lower_mesh;
@@ -4706,7 +4834,7 @@ static int __netdev_upper_dev_link(struct net_device *dev,
4706 4834
4707rollback_lower_mesh: 4835rollback_lower_mesh:
4708 to_i = i; 4836 to_i = i;
4709 list_for_each_entry(i, &dev->lower_dev_list, list) { 4837 list_for_each_entry(i, &dev->all_adj_list.lower, list) {
4710 if (i == to_i) 4838 if (i == to_i)
4711 break; 4839 break;
4712 __netdev_adjacent_dev_unlink(i->dev, upper_dev); 4840 __netdev_adjacent_dev_unlink(i->dev, upper_dev);
@@ -4716,7 +4844,7 @@ rollback_lower_mesh:
4716 4844
4717rollback_upper_mesh: 4845rollback_upper_mesh:
4718 to_i = i; 4846 to_i = i;
4719 list_for_each_entry(i, &upper_dev->upper_dev_list, list) { 4847 list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) {
4720 if (i == to_i) 4848 if (i == to_i)
4721 break; 4849 break;
4722 __netdev_adjacent_dev_unlink(dev, i->dev); 4850 __netdev_adjacent_dev_unlink(dev, i->dev);
@@ -4727,8 +4855,8 @@ rollback_upper_mesh:
4727rollback_mesh: 4855rollback_mesh:
4728 to_i = i; 4856 to_i = i;
4729 to_j = j; 4857 to_j = j;
4730 list_for_each_entry(i, &dev->lower_dev_list, list) { 4858 list_for_each_entry(i, &dev->all_adj_list.lower, list) {
4731 list_for_each_entry(j, &upper_dev->upper_dev_list, list) { 4859 list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) {
4732 if (i == to_i && j == to_j) 4860 if (i == to_i && j == to_j)
4733 break; 4861 break;
4734 __netdev_adjacent_dev_unlink(i->dev, j->dev); 4862 __netdev_adjacent_dev_unlink(i->dev, j->dev);
@@ -4737,7 +4865,7 @@ rollback_mesh:
4737 break; 4865 break;
4738 } 4866 }
4739 4867
4740 __netdev_adjacent_dev_unlink(dev, upper_dev); 4868 __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
4741 4869
4742 return ret; 4870 return ret;
4743} 4871}
@@ -4755,7 +4883,7 @@ rollback_mesh:
4755int netdev_upper_dev_link(struct net_device *dev, 4883int netdev_upper_dev_link(struct net_device *dev,
4756 struct net_device *upper_dev) 4884 struct net_device *upper_dev)
4757{ 4885{
4758 return __netdev_upper_dev_link(dev, upper_dev, false); 4886 return __netdev_upper_dev_link(dev, upper_dev, false, NULL);
4759} 4887}
4760EXPORT_SYMBOL(netdev_upper_dev_link); 4888EXPORT_SYMBOL(netdev_upper_dev_link);
4761 4889
@@ -4773,10 +4901,18 @@ EXPORT_SYMBOL(netdev_upper_dev_link);
4773int netdev_master_upper_dev_link(struct net_device *dev, 4901int netdev_master_upper_dev_link(struct net_device *dev,
4774 struct net_device *upper_dev) 4902 struct net_device *upper_dev)
4775{ 4903{
4776 return __netdev_upper_dev_link(dev, upper_dev, true); 4904 return __netdev_upper_dev_link(dev, upper_dev, true, NULL);
4777} 4905}
4778EXPORT_SYMBOL(netdev_master_upper_dev_link); 4906EXPORT_SYMBOL(netdev_master_upper_dev_link);
4779 4907
4908int 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}
4914EXPORT_SYMBOL(netdev_master_upper_dev_link_private);
4915
4780/** 4916/**
4781 * netdev_upper_dev_unlink - Removes a link to upper device 4917 * netdev_upper_dev_unlink - Removes a link to upper device
4782 * @dev: device 4918 * @dev: device
@@ -4791,29 +4927,59 @@ void netdev_upper_dev_unlink(struct net_device *dev,
4791 struct netdev_adjacent *i, *j; 4927 struct netdev_adjacent *i, *j;
4792 ASSERT_RTNL(); 4928 ASSERT_RTNL();
4793 4929
4794 __netdev_adjacent_dev_unlink(dev, upper_dev); 4930 __netdev_adjacent_dev_unlink_neighbour(dev, upper_dev);
4795 4931
4796 /* 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
4797 * devices from all upper_dev's upper devices and vice 4933 * devices from all upper_dev's upper devices and vice
4798 * versa, to maintain the graph relationship. 4934 * versa, to maintain the graph relationship.
4799 */ 4935 */
4800 list_for_each_entry(i, &dev->lower_dev_list, list) 4936 list_for_each_entry(i, &dev->all_adj_list.lower, list)
4801 list_for_each_entry(j, &upper_dev->upper_dev_list, list) 4937 list_for_each_entry(j, &upper_dev->all_adj_list.upper, list)
4802 __netdev_adjacent_dev_unlink(i->dev, j->dev); 4938 __netdev_adjacent_dev_unlink(i->dev, j->dev);
4803 4939
4804 /* remove also the devices itself from lower/upper device 4940 /* remove also the devices itself from lower/upper device
4805 * list 4941 * list
4806 */ 4942 */
4807 list_for_each_entry(i, &dev->lower_dev_list, list) 4943 list_for_each_entry(i, &dev->all_adj_list.lower, list)
4808 __netdev_adjacent_dev_unlink(i->dev, upper_dev); 4944 __netdev_adjacent_dev_unlink(i->dev, upper_dev);
4809 4945
4810 list_for_each_entry(i, &upper_dev->upper_dev_list, list) 4946 list_for_each_entry(i, &upper_dev->all_adj_list.upper, list)
4811 __netdev_adjacent_dev_unlink(dev, i->dev); 4947 __netdev_adjacent_dev_unlink(dev, i->dev);
4812 4948
4813 call_netdevice_notifiers(NETDEV_CHANGEUPPER, dev); 4949 call_netdevice_notifiers(NETDEV_CHANGEUPPER, dev);
4814} 4950}
4815EXPORT_SYMBOL(netdev_upper_dev_unlink); 4951EXPORT_SYMBOL(netdev_upper_dev_unlink);
4816 4952
4953void *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}
4966EXPORT_SYMBOL(netdev_lower_dev_get_private_rcu);
4967
4968void *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}
4981EXPORT_SYMBOL(netdev_lower_dev_get_private);
4982
4817static void dev_change_rx_flags(struct net_device *dev, int flags) 4983static void dev_change_rx_flags(struct net_device *dev, int flags)
4818{ 4984{
4819 const struct net_device_ops *ops = dev->netdev_ops; 4985 const struct net_device_ops *ops = dev->netdev_ops;
@@ -6069,8 +6235,10 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
6069 INIT_LIST_HEAD(&dev->napi_list); 6235 INIT_LIST_HEAD(&dev->napi_list);
6070 INIT_LIST_HEAD(&dev->unreg_list); 6236 INIT_LIST_HEAD(&dev->unreg_list);
6071 INIT_LIST_HEAD(&dev->link_watch_list); 6237 INIT_LIST_HEAD(&dev->link_watch_list);
6072 INIT_LIST_HEAD(&dev->upper_dev_list); 6238 INIT_LIST_HEAD(&dev->adj_list.upper);
6073 INIT_LIST_HEAD(&dev->lower_dev_list); 6239 INIT_LIST_HEAD(&dev->adj_list.lower);
6240 INIT_LIST_HEAD(&dev->all_adj_list.upper);
6241 INIT_LIST_HEAD(&dev->all_adj_list.lower);
6074 dev->priv_flags = IFF_XMIT_DST_RELEASE; 6242 dev->priv_flags = IFF_XMIT_DST_RELEASE;
6075 setup(dev); 6243 setup(dev);
6076 6244