aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/core/dev.c239
1 files changed, 235 insertions, 4 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index bddb2f2ccaa9..53a9fefbc9af 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4600,6 +4600,232 @@ static int __init dev_proc_init(void)
4600#endif /* CONFIG_PROC_FS */ 4600#endif /* CONFIG_PROC_FS */
4601 4601
4602 4602
4603struct netdev_upper {
4604 struct net_device *dev;
4605 bool master;
4606 struct list_head list;
4607 struct rcu_head rcu;
4608 struct list_head search_list;
4609};
4610
4611static void __append_search_uppers(struct list_head *search_list,
4612 struct net_device *dev)
4613{
4614 struct netdev_upper *upper;
4615
4616 list_for_each_entry(upper, &dev->upper_dev_list, list) {
4617 /* check if this upper is not already in search list */
4618 if (list_empty(&upper->search_list))
4619 list_add_tail(&upper->search_list, search_list);
4620 }
4621}
4622
4623static bool __netdev_search_upper_dev(struct net_device *dev,
4624 struct net_device *upper_dev)
4625{
4626 LIST_HEAD(search_list);
4627 struct netdev_upper *upper;
4628 struct netdev_upper *tmp;
4629 bool ret = false;
4630
4631 __append_search_uppers(&search_list, dev);
4632 list_for_each_entry(upper, &search_list, search_list) {
4633 if (upper->dev == upper_dev) {
4634 ret = true;
4635 break;
4636 }
4637 __append_search_uppers(&search_list, upper->dev);
4638 }
4639 list_for_each_entry_safe(upper, tmp, &search_list, search_list)
4640 INIT_LIST_HEAD(&upper->search_list);
4641 return ret;
4642}
4643
4644static struct netdev_upper *__netdev_find_upper(struct net_device *dev,
4645 struct net_device *upper_dev)
4646{
4647 struct netdev_upper *upper;
4648
4649 list_for_each_entry(upper, &dev->upper_dev_list, list) {
4650 if (upper->dev == upper_dev)
4651 return upper;
4652 }
4653 return NULL;
4654}
4655
4656/**
4657 * netdev_has_upper_dev - Check if device is linked to an upper device
4658 * @dev: device
4659 * @upper_dev: upper device to check
4660 *
4661 * Find out if a device is linked to specified upper device and return true
4662 * in case it is. Note that this checks only immediate upper device,
4663 * not through a complete stack of devices. The caller must hold the RTNL lock.
4664 */
4665bool netdev_has_upper_dev(struct net_device *dev,
4666 struct net_device *upper_dev)
4667{
4668 ASSERT_RTNL();
4669
4670 return __netdev_find_upper(dev, upper_dev);
4671}
4672EXPORT_SYMBOL(netdev_has_upper_dev);
4673
4674/**
4675 * netdev_has_any_upper_dev - Check if device is linked to some device
4676 * @dev: device
4677 *
4678 * Find out if a device is linked to an upper device and return true in case
4679 * it is. The caller must hold the RTNL lock.
4680 */
4681bool netdev_has_any_upper_dev(struct net_device *dev)
4682{
4683 ASSERT_RTNL();
4684
4685 return !list_empty(&dev->upper_dev_list);
4686}
4687EXPORT_SYMBOL(netdev_has_any_upper_dev);
4688
4689/**
4690 * netdev_master_upper_dev_get - Get master upper device
4691 * @dev: device
4692 *
4693 * Find a master upper device and return pointer to it or NULL in case
4694 * it's not there. The caller must hold the RTNL lock.
4695 */
4696struct net_device *netdev_master_upper_dev_get(struct net_device *dev)
4697{
4698 struct netdev_upper *upper;
4699
4700 ASSERT_RTNL();
4701
4702 if (list_empty(&dev->upper_dev_list))
4703 return NULL;
4704
4705 upper = list_first_entry(&dev->upper_dev_list,
4706 struct netdev_upper, list);
4707 if (likely(upper->master))
4708 return upper->dev;
4709 return NULL;
4710}
4711EXPORT_SYMBOL(netdev_master_upper_dev_get);
4712
4713/**
4714 * netdev_master_upper_dev_get_rcu - Get master upper device
4715 * @dev: device
4716 *
4717 * Find a master upper device and return pointer to it or NULL in case
4718 * it's not there. The caller must hold the RCU read lock.
4719 */
4720struct net_device *netdev_master_upper_dev_get_rcu(struct net_device *dev)
4721{
4722 struct netdev_upper *upper;
4723
4724 upper = list_first_or_null_rcu(&dev->upper_dev_list,
4725 struct netdev_upper, list);
4726 if (upper && likely(upper->master))
4727 return upper->dev;
4728 return NULL;
4729}
4730EXPORT_SYMBOL(netdev_master_upper_dev_get_rcu);
4731
4732static int __netdev_upper_dev_link(struct net_device *dev,
4733 struct net_device *upper_dev, bool master)
4734{
4735 struct netdev_upper *upper;
4736
4737 ASSERT_RTNL();
4738
4739 if (dev == upper_dev)
4740 return -EBUSY;
4741
4742 /* To prevent loops, check if dev is not upper device to upper_dev. */
4743 if (__netdev_search_upper_dev(upper_dev, dev))
4744 return -EBUSY;
4745
4746 if (__netdev_find_upper(dev, upper_dev))
4747 return -EEXIST;
4748
4749 if (master && netdev_master_upper_dev_get(dev))
4750 return -EBUSY;
4751
4752 upper = kmalloc(sizeof(*upper), GFP_KERNEL);
4753 if (!upper)
4754 return -ENOMEM;
4755
4756 upper->dev = upper_dev;
4757 upper->master = master;
4758 INIT_LIST_HEAD(&upper->search_list);
4759
4760 /* Ensure that master upper link is always the first item in list. */
4761 if (master)
4762 list_add_rcu(&upper->list, &dev->upper_dev_list);
4763 else
4764 list_add_tail_rcu(&upper->list, &dev->upper_dev_list);
4765 dev_hold(upper_dev);
4766
4767 return 0;
4768}
4769
4770/**
4771 * netdev_upper_dev_link - Add a link to the upper device
4772 * @dev: device
4773 * @upper_dev: new upper device
4774 *
4775 * Adds a link to device which is upper to this one. The caller must hold
4776 * the RTNL lock. On a failure a negative errno code is returned.
4777 * On success the reference counts are adjusted and the function
4778 * returns zero.
4779 */
4780int netdev_upper_dev_link(struct net_device *dev,
4781 struct net_device *upper_dev)
4782{
4783 return __netdev_upper_dev_link(dev, upper_dev, false);
4784}
4785EXPORT_SYMBOL(netdev_upper_dev_link);
4786
4787/**
4788 * netdev_master_upper_dev_link - Add a master link to the upper device
4789 * @dev: device
4790 * @upper_dev: new upper device
4791 *
4792 * Adds a link to device which is upper to this one. In this case, only
4793 * one master upper device can be linked, although other non-master devices
4794 * might be linked as well. The caller must hold the RTNL lock.
4795 * On a failure a negative errno code is returned. On success the reference
4796 * counts are adjusted and the function returns zero.
4797 */
4798int netdev_master_upper_dev_link(struct net_device *dev,
4799 struct net_device *upper_dev)
4800{
4801 return __netdev_upper_dev_link(dev, upper_dev, true);
4802}
4803EXPORT_SYMBOL(netdev_master_upper_dev_link);
4804
4805/**
4806 * netdev_upper_dev_unlink - Removes a link to upper device
4807 * @dev: device
4808 * @upper_dev: new upper device
4809 *
4810 * Removes a link to device which is upper to this one. The caller must hold
4811 * the RTNL lock.
4812 */
4813void netdev_upper_dev_unlink(struct net_device *dev,
4814 struct net_device *upper_dev)
4815{
4816 struct netdev_upper *upper;
4817
4818 ASSERT_RTNL();
4819
4820 upper = __netdev_find_upper(dev, upper_dev);
4821 if (!upper)
4822 return;
4823 list_del_rcu(&upper->list);
4824 dev_put(upper_dev);
4825 kfree_rcu(upper, rcu);
4826}
4827EXPORT_SYMBOL(netdev_upper_dev_unlink);
4828
4603/** 4829/**
4604 * netdev_set_master - set up master pointer 4830 * netdev_set_master - set up master pointer
4605 * @slave: slave device 4831 * @slave: slave device
@@ -4613,19 +4839,23 @@ static int __init dev_proc_init(void)
4613int netdev_set_master(struct net_device *slave, struct net_device *master) 4839int netdev_set_master(struct net_device *slave, struct net_device *master)
4614{ 4840{
4615 struct net_device *old = slave->master; 4841 struct net_device *old = slave->master;
4842 int err;
4616 4843
4617 ASSERT_RTNL(); 4844 ASSERT_RTNL();
4618 4845
4619 if (master) { 4846 if (master) {
4620 if (old) 4847 if (old)
4621 return -EBUSY; 4848 return -EBUSY;
4622 dev_hold(master); 4849 err = netdev_master_upper_dev_link(slave, master);
4850 if (err)
4851 return err;
4623 } 4852 }
4624 4853
4625 slave->master = master; 4854 slave->master = master;
4626 4855
4627 if (old) 4856 if (old)
4628 dev_put(old); 4857 netdev_upper_dev_unlink(slave, master);
4858
4629 return 0; 4859 return 0;
4630} 4860}
4631EXPORT_SYMBOL(netdev_set_master); 4861EXPORT_SYMBOL(netdev_set_master);
@@ -5503,8 +5733,8 @@ static void rollback_registered_many(struct list_head *head)
5503 if (dev->netdev_ops->ndo_uninit) 5733 if (dev->netdev_ops->ndo_uninit)
5504 dev->netdev_ops->ndo_uninit(dev); 5734 dev->netdev_ops->ndo_uninit(dev);
5505 5735
5506 /* Notifier chain MUST detach us from master device. */ 5736 /* Notifier chain MUST detach us all upper devices. */
5507 WARN_ON(dev->master); 5737 WARN_ON(netdev_has_any_upper_dev(dev));
5508 5738
5509 /* Remove entries from kobject tree */ 5739 /* Remove entries from kobject tree */
5510 netdev_unregister_kobject(dev); 5740 netdev_unregister_kobject(dev);
@@ -6212,6 +6442,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
6212 INIT_LIST_HEAD(&dev->napi_list); 6442 INIT_LIST_HEAD(&dev->napi_list);
6213 INIT_LIST_HEAD(&dev->unreg_list); 6443 INIT_LIST_HEAD(&dev->unreg_list);
6214 INIT_LIST_HEAD(&dev->link_watch_list); 6444 INIT_LIST_HEAD(&dev->link_watch_list);
6445 INIT_LIST_HEAD(&dev->upper_dev_list);
6215 dev->priv_flags = IFF_XMIT_DST_RELEASE; 6446 dev->priv_flags = IFF_XMIT_DST_RELEASE;
6216 setup(dev); 6447 setup(dev);
6217 6448